What is useReducer Hook in React?

This article provides a comprehensive overview of the useReducer hook in React. You will learn what useReducer is, how it differs from the more common useState hook, and when you should use it. Finally, we will walk through the basic syntax and a practical code example to help you implement it in your own applications.

Understanding useReducer

The useReducer hook is a built-in React hook used for managing complex state logic in functional components. It is similar to the useState hook, but it is modeled after the reducer pattern found in Redux.

Instead of updating the state directly, you dispatch “actions” that describe what happened. A dedicated “reducer” function then intercepts these actions and determines how the state should transition from its current value to the next value.

When to Use useReducer vs. useState

While useState is excellent for simple, independent state variables (like a boolean toggle or a text input), it can become messy when: * Your state involves multiple sub-values or complex nested objects. * The next state depends on the previous state. * Different state variables depend on one another.

In these scenarios, useReducer is the better choice. It centralizes state transitions, makes state updates predictable, and improves code readability by separating state logic from UI rendering.

The Syntax of useReducer

The useReducer hook accepts two primary arguments and returns an array with two elements:

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

Practical Example: A Simple Counter

Here is a step-by-step example of how to implement useReducer to manage a simple counter application.

Step 1: Define the Reducer Function

The reducer function contains a switch statement to handle different action types.

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    case 'reset':
      return { count: 0 };
    default:
      throw new Error(`Unhandled action type: ${action.type}`);
  }
}

Step 2: Use the Hook in a Component

Pass the reducer function and the initialState to the hook inside your component, and use the dispatch function inside your event handlers.

import React, { useReducer } from 'react';

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

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
      <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
    </div>
  );
}

export default Counter;

In this example, clicking any button calls dispatch with an object containing a type. The reducer function receives this action, evaluates the type in the switch statement, and returns the updated state object, causing the component to re-render with the new count.