With the introduction of hooks in React, we can manage states now not only in class components but also in functional components as well. When I got started with react I was using class components only to manage any local states that needed to be modified. After a while, I wanted to learn to use hooks so I could integrate various functions to my functional components. So I started learning to implement different hooks like: ‘useState’, ‘useRef’, useEffect etc. In this post I will explain my understanding and implementation of ‘useReducer’ hook.
To manage a component state in React, I’ve used useState hook before. It’s pretty straight forward and by calling an updater function like ‘setState’ I can modify and update the state.
const [counter, setCounter] = useState(0)
setCounter(prevCount => prevCount - 1)
But when the states gets more complex and deeply nested, calling these setState function gets large and unmanageable. That’s where we can use useReducer hooks.
I have had previous experiences with Redux, and useReducer works the same way how I’ve used Reducers in Redux to manage states in the redux store. Just like in the Redux, a reducer is a ‘pure function’ and what it means is that it takes in an input and returns an output based on a dispatched action but without modifying the original input.
(currentState, action) => newState
Reducers helps keeping states centralized and allows components to send actions to modify and alter complex states. To see it in realtime I used a simple counter component.
First thing I did was to import useReducer from react.
import React, { useReducer } from 'react';
Then I wrote a simple functional component and initiate the state by using useReducer.
const Counter = () => {
const [count, dispatch] = useReducer(reducer, 0)
return (
<>
Counter: {count}
<button onClick={() => dispatch('INCREMENT')}>+</button> <button onClick={() => dispatch('DECREMENT')}>-</button>
</>
)
}
useReducer takes a reducer function and an initial state. So I wrote the reducer function like this:
const reducer = (state, action) => {
switch (action) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
throw new Error()
}
}
That was it. A simple way to incorporate reducer to a functional component. The completed code looked like this:
Thank you for reading. Any feedback and suggestion will be appreciated.