Learn Redux in minutes using React Hooks
Learning how Redux manages states using useContext + useReducer hooks as examples
TL;DR
- State management
- Redux = useContext + useReducers
- Redux v/s React Hooks
Prerequisite: Familiarity with useContext and useReducer Hooks
State Management
State Management is the very basis of every Web application, it is the state which defines the view of our app, as the user interacts with the app the state gets modified, and hence the view.
So how to handle a task which is responsible for what the UI should look like.
Redux is one of the most famous state management libraries out there and also the combination of useContext + useReducer for providing and modifying states.
Redux = useContext + useReducer
So now let's go ahead and look at how Redux handles states, Redux has a store which acts as the useContext hook it has a provider and we use useSelector Hook(provided by Redux) to access the context of that provider
import { configureStore } from '@reduxjs/toolkit'
export const store = configureStore({
reducer: {},
})
But in Redux unlike useContext rather than having multiple Providers for different reducers, we have one single source which helps us write less code and acts as a single point of truth
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import { store } from './app/store'
import { Provider } from 'react-redux'
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
Now Redux has slices that contain the initial state and actions(functions to manipulate the state) createSlice is similar to useReducer. They have an extra property, they can manipulate state objects using Immer saving us from the hefty task of destructuring those deeply buried values inside nested objects
import { createSlice } from '@reduxjs/toolkit'
const initialState = {
value: 0,
}
export const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state) => {
// Redux Toolkit allows us to write "mutating" logic in reducers. It
// doesn't actually mutate the state because it uses the Immer library,
// which detects changes to a "draft state" and produces a brand new
// immutable state based off those changes
state.value += 1
},
decrement: (state) => {
state.value -= 1
},
incrementByAmount: (state, action) => {
state.value += action.payload
},
},
})
// Action creators are generated for each case reducer function
export const { increment, decrement, incrementByAmount } = counterSlice.actions
export default counterSlice.reducer
Just as useReducer has a dispatch function to call the reducer with a specific action,
in Redux we a similar dispatch()
function which is provided by useDispatch
hook(provided by redux)
const dispatch = useDispatch()
dispatch(increment())
Redux v/s React Hooks
The answer as you expected is "It depends"
Both sides have their own pros and cons, Redux comes in handy when you have a lot of states to handle just like in large complicated apps where it helps untangle the complexity of what triggered the rerender. While useContext + useReducer gets the job done pretty good but as the apps become large and complicated it becomes difficult to handle everything with just them Redux has lots of other functionalities which help us out.
Conclusion
So as a rule of thumb if you are building some side or personal projects or inhouse small apps at your work React Hooks works perfectly fine and in fact is better but if the app you are building is for a large number of users or will scale up in the future then go for Redux