Amruta Nejkar

Introduction to React useReducer

useReducer is a React Hook that gives us more control over state management than useState, making it easier to manage complex states. I

Its basic structure is :

React useReducer can be used to manage state that depends on previous states, and efficiently manage multiple, complex states.

How does useReducer work?

The useReducer Hook is used to store and update states, just like the useState Hook. It accepts a reducer function as its first parameter and the initial state as the second.

useReducer returns an array that holds the current state value and a dispatch function to which you can pass an action and later invoke it. While this is similar to the pattern Redux uses, there are a few differences.

For example, the useReducer function is tightly coupled to a specific reducer. We dispatch action objects to that reducer only, whereas in Redux, the dispatch function sends the action object to the store. At the time of dispatch, the components don’t need to know which reducer will process the action.

 The reducer function

It is a pure function that accepts state and action as parameters and returns an updated state. 

Look at its structure below:

The action parameter helps us define how to change our state. It can be a single value or an object with a label (type) and some data to update the state (payload). It gets its data from useReducer’s dispatch function.

We use conditionals (typically a switch statement) to determine what code to execute based on the type of action (action.type).

Understanding useReducer with examples

Example 1: A simple counter

In the code above:

  • Our initialState is 0, so when the component is initially displayed on the browser, <h1>{state}</h1> shows 0.
  • When a user clicks on the button, it triggers the dispatch, which sets the value of action to 1, and runs the reducer function.
  • The reducer function runs the block of code inside it, which returns the sum of the current state and the action.
  • Its result is then passed as the new, updated state and displayed on the browser.

useState vs useReducer

Fundamentally, we can manage our state with either useState or useReducer. As a matter of fact, useState implements useReducer under the hood.

The significant difference between both hooks is that with useReducer, we can avoid passing callbacks through different levels of our component and use the dispatch function instead, improving performance for components with deep updates.

Declaring the state

We declare useState like this:

In useReducer, it is done like this:

Updating state

In useState, we update our state like this:

In useReducer, we do it like this:&gt;

The value of newState is then sent to our reducer function, which updates the state.

When to use useReducer Hook

The current state depends on the previous state

In Example 2, we increment or decrement the counter based on the previous value in the state. useReducer gives a predictable state transition when moving from one state to another.

Managing complex states or multiple states

When working with complex states such as nested objects, useReducer helps us determine how the state is updated based on the particular action triggered. In Example 4, its state is an object which contains a parameter (items) that is an array of objects. With useReducer, we assigned action types such as ‘add’, ‘input’, and ‘delete’ to update different parts of the state.

Updating state based on another state

In Example 4, to add a new item to the items array, we need to get the input value from the user first. With useReducer, we get the current input value from our state and use it to create a new object, which we then added to our items array.