Mastering Complex State in React Using use Reducer Hook

By Priya
May 18, 2025

Follow us on


Learn how to manage complex state in React applications using the use Reducer hook with clear explanations and step-by-step code examples.

Mastering Complex State in React Using use Reducer Hook

React applications often need to handle complex states — like deeply nested objects or multiple interrelated values. While useState works well for simple states, for more intricate logic, useReducer is a better tool.

In this article, we’ll break down how useReducer works, when to use it, and how to implement it in your React app — step by step in simple language.


📌 What is useReducer?

useReducer is a React Hook that is used for managing state in a more predictable and scalable way than useState, especially when:

  • The state logic is complex

  • The next state depends on the previous state

  • Multiple pieces of state are updated together

It works similarly to how reducers work in Redux.


🧠 Basic Syntax of useReducer

const [state, dispatch] = useReducer(reducerFunction, initialState);
  • state → The current state

  • dispatch → A function used to send actions (requests to change state)

  • reducerFunction → A function that tells how to update the state

  • initialState → The default state


📦 Example Use Case – A Counter with Multiple Actions

Let’s say we want to build a counter with the following features:

  • Increase by 1

  • Decrease by 1

  • Reset to 0

  • Set a custom value

This is already more complex than what useState comfortably handles. Here's how we can use useReducer.


✅ Step-by-Step Implementation

1. Setup a React Project (Skip if already done)

npx create-react-app useReducer-example
cd useReducer-example
npm start

2. Create Counter.js component

import React, { useReducer } from "react";

// Step 3: Define the initial state
const initialState = { count: 0 };

// Step 4: Define the 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 };
    case "set":
      return { count: action.payload };
    default:
      return state;
  }
}

// Step 5: Build the component
function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div style={{ textAlign: "center", marginTop: "50px" }}>
      <h2>Counter: {state.count}</h2>
      <button onClick={() => dispatch({ type: "increment" })}>+1</button>
      <button onClick={() => dispatch({ type: "decrement" })}>-1</button>
      <button onClick={() => dispatch({ type: "reset" })}>Reset</button>
      <button onClick={() => dispatch({ type: "set", payload: 100 })}>
        Set to 100
      </button>
    </div>
  );
}

export default Counter;

6. Use this component in App.js

import React from "react";
import Counter from "./Counter";

function App() {
  return (
    <div>
      <Counter />
    </div>
  );
}

export default App;

🔍 Explanation (Step by Step)

Step 3: initialState
This is the starting value of our state object: { count: 0 }.

Step 4: reducer function
This function accepts state and action, and returns the new state depending on the action.type.

Each case defines what should happen:

  • "increment": Adds 1

  • "decrement": Subtracts 1

  • "reset": Resets to 0

  • "set": Sets it to a specific number passed via payload

Step 5: useReducer Hook
We pass the reducer function and initial state.
It gives us the current state (state.count) and dispatch() to trigger actions.

UI Buttons
Each button calls dispatch() with a specific action type to update the state.


🛠 Why Use useReducer Instead of useState?

Feature                    useState                useReducer
Best For   Simple states  Complex states
Updates   Direct  Based on actions 
Structure  Minimal  Predictable
Readability  Decrease with logic  Clear separation of logic 

🔄 Real-World Use Cases

You should consider useReducer in:

  • Forms with multiple fields and validation

  • Shopping carts with add/remove item logic

  • Toggle systems with various modes (like dark/light themes)

  • Complex UI states like filters, modals, etc.


📘 Bonus: Custom useReducer with Form

For practice, try building a form with fields like name, email, and message, and manage them with useReducer.


🚀 Conclusion

useReducer gives you clear control over complex state transitions in React apps. It’s an ideal alternative to useState when your state management becomes too intricate or tightly coupled. Once you get the hang of it, you’ll find your components easier to test, debug, and scale.

 


© 2025 Revolve Base. All rights reserved.