useReducer Hook

Loading concept...

🎭 The Magic Dispatch Machine: Understanding useReducer

Imagine you have a magical toy box that only changes when you give it special instruction cards…


🌟 What’s the Big Idea?

Remember when you played with building blocks? You could only do certain things with them:

  • ADD a block
  • REMOVE a block
  • CHANGE a block’s color

Now imagine having a magic helper who follows your instructions perfectly. You write down what you want on a card, hand it over, and BOOM—the helper does exactly that!

That’s useReducer! It’s React’s way of managing complex changes with clear, written instructions.


🎪 The Reducer Pattern: Your Rule Book

The Story

Think of a reducer like a very organized librarian. When you bring a book request:

  1. The librarian looks at what books are on the shelf (current state)
  2. Reads your request slip (action)
  3. Follows the exact rule for that request
  4. Returns the updated shelf (new state)
// Your librarian's rule book
function shelfReducer(shelf, request) {
  if (request.type === 'ADD_BOOK') {
    return [...shelf, request.book];
  }
  if (request.type === 'REMOVE_BOOK') {
    return shelf.filter(b => b !== request.book);
  }
  return shelf;
}

The Golden Rule 🌟

Same input = Same output. Always.

If you give the librarian the same shelf and same request, you ALWAYS get the same result. No surprises!


🎯 useReducer Basics: Your First Magic Machine

Setting Up the Magic

import { useReducer } from 'react';

// Step 1: Define your reducer (rule book)
function counterReducer(count, action) {
  switch (action.type) {
    case 'INCREMENT':
      return count + 1;
    case 'DECREMENT':
      return count - 1;
    case 'RESET':
      return 0;
    default:
      return count;
  }
}

// Step 2: Use it in your component
function Counter() {
  const [count, dispatch] = useReducer(
    counterReducer,  // rules
    0                // starting number
  );

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => dispatch({type: 'INCREMENT'})}>
        +1
      </button>
    </div>
  );
}

What You Get Back

graph TD A[useReducer] --> B[count] A --> C[dispatch] B --> D[Current value] C --> E[Function to send actions]
  • count = Your current state (the number right now)
  • dispatch = Your messenger (delivers action cards)

📬 Actions and Dispatch: Sending Instructions

Actions are Just Messages!

An action is a simple object that says:

  • What to do (type)
  • Details if needed (payload)
// Simple action - just the type
{ type: 'INCREMENT' }

// Action with extra info
{ type: 'ADD_TODO', payload: 'Buy milk' }

// Action with multiple details
{
  type: 'UPDATE_USER',
  payload: {
    name: 'Alex',
    age: 10
  }
}

Dispatch is Your Messenger

Think of dispatch like a mail carrier:

// You write the instruction
const instruction = { type: 'INCREMENT' };

// Dispatch delivers it
dispatch(instruction);

// Or write and send in one go!
dispatch({ type: 'INCREMENT' });

A Complete Example

function todoReducer(todos, action) {
  switch (action.type) {
    case 'ADD':
      return [...todos, {
        id: Date.now(),
        text: action.text,
        done: false
      }];
    case 'TOGGLE':
      return todos.map(todo =>
        todo.id === action.id
          ? {...todo, done: !todo.done}
          : todo
      );
    case 'DELETE':
      return todos.filter(
        todo => todo.id !== action.id
      );
    default:
      return todos;
  }
}

⚖️ Reducer vs useState: When to Use Which?

The Simple Choice Guide

Situation Use This
One simple value useState
Toggle on/off useState
Multiple related values useReducer
Complex update logic useReducer
Next state depends on previous useReducer

useState: Quick and Easy

// Perfect for simple stuff
const [name, setName] = useState('');
const [isOpen, setIsOpen] = useState(false);
const [count, setCount] = useState(0);

useReducer: Organized and Powerful

// Perfect for complex stuff
const [form, dispatch] = useReducer(
  formReducer,
  { name: '', email: '', errors: {} }
);

Visual Comparison

graph TD subgraph useState A[State] --> B[setState] B --> C[New State] end subgraph useReducer D[State] --> E[dispatch action] E --> F[Reducer] F --> G[New State] end

The Real Difference

useState is like texting your friend:

“Change the number to 5”

useReducer is like filling out a form:

“Request Type: UPDATE_SCORE” “Details: player=1, points=5”

Both work! But forms are better when you have many types of changes.


🎨 When useReducer Shines

Example: Shopping Cart

function cartReducer(cart, action) {
  switch (action.type) {
    case 'ADD_ITEM':
      const exists = cart.find(
        i => i.id === action.item.id
      );
      if (exists) {
        return cart.map(i =>
          i.id === action.item.id
            ? {...i, qty: i.qty + 1}
            : i
        );
      }
      return [...cart, {...action.item, qty: 1}];

    case 'REMOVE_ITEM':
      return cart.filter(
        i => i.id !== action.id
      );

    case 'UPDATE_QTY':
      return cart.map(i =>
        i.id === action.id
          ? {...i, qty: action.qty}
          : i
      );

    case 'CLEAR':
      return [];

    default:
      return cart;
  }
}

With useState, you’d need 4 different functions. With useReducer, one reducer handles everything!


🎯 Key Takeaways

  1. useReducer = useState for complex state
  2. Reducer = Pure function: (state, action) → new state
  3. Action = Object with type and optional payload
  4. Dispatch = Function to send actions to reducer
  5. Use useState for simple, useReducer for complex

đź’ˇ Remember This Analogy

useReducer is like a restaurant order system:

  • Your state = Current order
  • Your action = Order slip (“ADD pizza”, “REMOVE salad”)
  • The reducer = Kitchen rules for handling orders
  • Dispatch = Waiter who takes your order to the kitchen

You don’t go into the kitchen yourself. You tell the waiter what you want, and the kitchen follows its rules to prepare your order!


Now you understand useReducer! It’s not scary—it’s just a more organized way to manage state when things get complex. 🚀

Loading story...

No Story Available

This concept doesn't have a story yet.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Interactive Preview

Interactive - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Interactive Content

This concept doesn't have interactive content yet.

Cheatsheet Preview

Cheatsheet - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Cheatsheet Available

This concept doesn't have a cheatsheet yet.

Quiz Preview

Quiz - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Quiz Available

This concept doesn't have a quiz yet.