React Js

React JS Tutorial Learn React JS, the powerful JavaScript library for building dynamic and interactive user interfaces. This beginner-friendly tutorial covers core concepts like components, state, props, and hooks, with hands-on projects to create responsive web apps. Perfect for aspiring developers looking to master modern front-end development.

React useReducer Hook

25 April 2025 | Category:

The useReducer Hook in React is like an advanced version of useState. It’s used for managing more complex state logic, especially when:

  • Multiple values are connected
  • State updates depend on previous state
  • You want a Redux-like reducer pattern without using Redux

🔧 Why use useReducer?

If useState is like a toolbox, then useReducer is like a workshop – more organized, powerful, and scalable.

Use it when:

  • You have multiple related pieces of state
  • You need clear state transitions
  • You want predictable logic using action and type

🧪 Syntax

const [state, dispatch] = useReducer(reducerFunction, initialState);
  • state: current state object or value
  • dispatch: function to send actions to the reducer
  • reducerFunction: function that handles state updates
  • initialState: the starting value of the state

📦 Importing useReducer

import { useReducer } from 'react';

🔁 useReducer vs useState

FeatureuseStateuseReducer
Simple state✅ Easy⚠️ Overkill
Complex logic❌ Can get messy✅ Cleaner with reducer
Multiple states❌ Scattered✅ Centralized
Redux-like workflow❌ Not possible✅ Very similar

✅ Example 1: Counter with useReducer

Let’s build a simple counter to understand how useReducer works.

🧠 Step 1: Reducer function

function counterReducer(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;
  }
}

🧠 Step 2: Component using the reducer

import React, { useReducer } from 'react';

const initialState = { count: 0 };

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

  return (
    <div>
      <h2>Count: {state.count}</h2>
      <button onClick={() => dispatch({ type: 'DECREMENT' })}>-</button>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button>
      <button onClick={() => dispatch({ type: 'RESET' })}>Reset</button>
    </div>
  );
}

🧠 Explanation:

  • We pass an action object to dispatch, like { type: 'INCREMENT' }
  • The reducer function updates the state based on the type

✅ Example 2: Todo List with useReducer

🧠 Step 1: Reducer function

function todoReducer(state, action) {
  switch (action.type) {
    case 'ADD':
      return [...state, { id: Date.now(), text: action.payload }];
    case 'DELETE':
      return state.filter(todo => todo.id !== action.payload);
    default:
      return state;
  }
}

🧠 Step 2: Component

import React, { useReducer, useState } from 'react';

function TodoApp() {
  const [todos, dispatch] = useReducer(todoReducer, []);
  const [input, setInput] = useState('');

  const handleAdd = () => {
    if (input.trim()) {
      dispatch({ type: 'ADD', payload: input });
      setInput('');
    }
  };

  return (
    <div>
      <h2>Todo List</h2>
      <input
        value={input}
        onChange={(e) => setInput(e.target.value)}
        placeholder="Enter a todo"
      />
      <button onClick={handleAdd}>Add</button>
      <ul>
        {todos.map(todo => (
          <li key={todo.id}>
            {todo.text}{' '}
            <button onClick={() => dispatch({ type: 'DELETE', payload: todo.id })}>
              Delete
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

🛠 Benefits of useReducer

✅ Organizes complex state logic
✅ Clean separation of logic and UI
✅ Predictable state updates
✅ Scalable – great for large apps


📋 Summary

ConceptDescription
useReducerHook to manage complex state logic
stateCurrent state value
dispatch()Function to send actions to the reducer
reducer()Pure function to handle state changes
actionObject with a type and optional payload

🔥 Bonus Tips

  • Reducers should be pure functions (no API calls, no side effects).
  • Combine useReducer with useContext for global state management.
  • Works great for form state, toggles, checkboxes, dynamic lists, and more.