R

React Handbook

Clean • Professional

React useReducer Hook – Advanced State Management

2 minute

React useReducer Hook

In React, the useReducer hook provides a powerful alternative to useState for managing complex or nested state logic. It’s particularly useful when your component has multiple related state variables or when state updates depend on previous state values.

While useState is perfect for simple state updates, useReducer brings predictable state transitions and centralized logic, making your code cleaner and easier to maintain.

What is useReducer?

The useReducer hook works similarly to reducers in Redux:

  • You define a reducer function that takes the current state and an action.
  • The reducer returns the new state based on the action.
  • You use dispatch to send actions to the reducer, updating state.

Syntax:

const [state, dispatch] = useReducer(reducer, initialState);
  • state → Current state value
  • dispatch → Function to send actions to the reducer
  • reducer → Function that calculates the next state
  • initialState → Initial state value

Example:

import React, { useReducer } from "react";

// Reducer function
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:
      return state;
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });

  return (
    <div>
      <h1>Count: {state.count}</h1>
      <button onClick={() => dispatch({ type: "increment" })}>+</button>
      <button onClick={() => dispatch({ type: "decrement" })}>-</button>
      <button onClick={() => dispatch({ type: "reset" })}>Reset</button>
    </div>
  );
}

export default Counter;

When to Use useReducer

useReducer is ideal when:

  1. State depends on previous values.
  2. You have multiple related state variables.
  3. You want centralized state logic instead of multiple useState calls.
  4. You need predictable updates similar to Redux but without external libraries.

Example – Multiple State Management:

const initialState = { count: 0, text: "" };

function reducer(state, action) {
  switch (action.type) {
    case "increment":
      return { ...state, count: state.count + 1 };
    case "setText":
      return { ...state, text: action.payload };
    default:
      return state;
  }
}

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

  return (
    <div>
      <h2>Count: {state.count}</h2>
      <inputtype="text"
        value={state.text}
        onChange={(e) => dispatch({ type: "setText", payload: e.target.value })}
      />
      <button onClick={() => dispatch({ type: "increment" })}>Increment</button>
    </div>
  );
}

Benefits of useReducer:

learn code with durgesh images

  1. Centralized State Logic – All state updates are handled in the reducer function.
  2. Predictable Updates – Clear action types and state changes make debugging easier.
  3. Better for Complex State – Ideal when useState becomes hard to manage.
  4. Easier Testing – Reducer functions are pure and can be tested independently.

Comparison: useState vs useReducer

FeatureuseStateuseReducer
Best ForSimple stateComplex or multiple related state
State UpdatesDirectly using setterThrough actions dispatched to reducer
State Logic LocationInline in componentCentralized in reducer function
ScalingHarder for complex stateEasier to maintain and scale


Article 0 of 0