Understanding useReducer in React

Reading Time: 3 minutes


Hooks are the new features added in React 16.8. They let you manage the state without writing a class. There are various hooks provided by React. One of them is useReducer. In this blog, we will understand useReducer and how we use it.

What is useReducer?

useReducer is the alternative to useState and is preferred to use when you have some complex states or when the next state value depends on the previous one. Rather than defining multiple states with useState we can easily manage states with useReducer.


Here is the syntax for using it:

const [state, dispatch] = useReducer(reducer, initialArgs, init);

This syntax accepts the reducer function as its first parameter.

Just like the useState, useReducer returns two values for which we use the array destructuring syntax.  The first argument is the current value of the state and the second is the dispatch function. 

Inside the useReducer, we have the reducer function as its first argument. initialArgs is the initial argument and the init refers to initializing the state lazily.

You can also simply just pass the reducer function and the initial state value.

Let us understand it with an example.

Demo for useReducer

First, create a react application.

npx create-react-app projectName

Note: While choosing a project name ensure that you lowercase letters only. With an upper case, you will get an error creating the application

cd projectName

Now move to the app.js file.

In this application, we will be modifying the example that we used in useState.

First, we need to import the useState like this:

import { useReducer } from "react";

Now, inside the app function lets define useReducer

const [state, dispatch] = useReducer(reducer, initialState);

Here we are passing the reducer function and the initialState so let us define both of them.

const initialState = {counter: 0};

Here we are setting the initial state. Setting the count value to zero.

We will be implementing increment, decrement, and reset counter so in the reducer function we need to define all three like this:

function reducer(state, action) {
   switch (action.type) {
     case 'INCREMENT':
       return {counter: state.counter + 1};
     case 'DECREMENT':
       return {counter: state.counter - 1};
     case 'RESET':
         return {counter: 0};
       throw new Error();

This function takes the state and the type of action as parameters. Then we check the action type by applying a switch statement covering all three and the default cases. See how we are referring to the count variable by state.count and returning value for each case.

Now in the HTML part let’s just display the counter value with three buttons to update its value.

<div className="container mt-3">
     <h3>Hi,this is a useReducer demo</h3>
     <p>Counter value: {state.counter}</p>
     <button type="button" class="btn btn-primary mr-3 " onClick={() => dispatch({type: 'INCREMENT'})}>Increment</button>
     <button type="button" class="btn btn-primary mr-3 " onClick={() => dispatch({type: 'DECREMENT'})}>Decrement</button>
     <button type="button" class="btn btn-primary mr-3 " onClick={() => dispatch({type: 'RESET'})}>Reset</button>

On each button click, we are dispatching an action (INCREMENT, DECREMENT, or RESET). This dispatched value is passed to the reducer function.

Now, try running the application using the npm start command.


So for the state management, you can use either useState or useReducer. If you have simpler states, go for useState and for more complex states or when you have related pieces of state prefer useReducer. To learn more about react hooks, refer here.

Written by 

Kiran Jeet Kaur is working as a Software Consultant in Knoldus. Her practice area is Front End. She is always open to learn new things. Her hobbies include watching movies and listening to music.