DEV Community

Cover image for useReducer() hook - Redux inside your component
kapeel kokane
kapeel kokane

Posted on

useReducer() hook - Redux inside your component

Hey There πŸ‘‹πŸΎ

Welcome to another post in the React demystified series.

Last week, we dug deep into the concept of Context in ReactπŸ‘‡πŸΎ

This week, we look into useReducer. Let's do it πŸ™ŒπŸΎ


Use case for useReducer

Let us try to explore the use cases where we would think about using the useReducer hook.
Before that, let us start off with a simple example. If we had to write the code for a simple component that holds a count as state, here's how we would write it:

const [count, setCount] = useState(0)
Enter fullscreen mode Exit fullscreen mode

The code above initialises the state to 0. We also have count through which we can access the current value of the state and setCount through which we can set a value of the state.

If we need to set the value of the state, it's quite straight forward, we call setCount:

setCount(10);
Enter fullscreen mode Exit fullscreen mode

But, what if we want to perform several operations on the state?

Operations on the state

Let us say that we have the state and several operations that we want to perform on the state like increment, decrement, reset (to 0), and set (to a custom value).

In that case, the code could be designed in such a way that we take the state, perform an action on it: INCREMENT, DECREMENT, RESET or SET and the we get the new value.

But what we defined above is the textbook definition of a reducer function!
A reducer function

And thus, our use case can be accomplished with the useReducer hook because it allows us to create a reducer inside of our React component.

Writing the reducer

With that understanding, let us write our reducer function. This is the function that React will call with the current state and the dispatched event type (whenever we dispatch one).

function reducerFunc(state, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1;
    case 'DECREMENT':
      return state - 1;
    case 'RESET':
      return 0;
    case 'SET':
      return action.val;
  }
}
Enter fullscreen mode Exit fullscreen mode

And that's it. With just those lines of code, we've set up state management for our complex use case.

☝🏾 Do not that the example of state to be a single number is just for the sake of explaining the concept and in react world, you would have complex objects as your core state and your would have to write logic inside your reducer to manage it correctly.

With that reducer, we can then initialise everything like so:

const [state, dispatch] = useReducer(reducerFunc, 0);
return (
    <main>
      <h1>Count : {state}</h1>
// rest of the code
Enter fullscreen mode Exit fullscreen mode

And, whenever we need to dispatch any changes to the state, we do something like this:

<button onClick={() => dispatch({ type: 'INCREMENT' })}>increment</button>
Enter fullscreen mode Exit fullscreen mode

And React will take care of the rest.

The reducer flow

Basically, this is what happens when we call the dispatch function provided to us by useReducer:

  • React calls the function that you initially supplied to useReducer and passes to it the arguments we supplied to dispatch.
  • The reducer function then makes some calculations based on some business logic.
  • The value that gets returned by the reducer function becomes the new state

This graphic sums it up well:

reducer flow

So basically, it is like having entire redux inside the scope of your React component.

Hope that clears a lot of confusion around the useReducer hook and the basic concept of a reducer function.

Cheers! πŸ™ŒπŸΎ

Top comments (0)