useReducer Basics

Syntax

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

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

dispatch({ type: "increment" }) calls the reducer with the current state and the action; whatever it returns becomes the new state.

Shopping Cart

Example

import { useReducer } from 'react';

function cartReducer(state, action) {
  switch (action.type) {
    case 'add':
      return [...state, action.item];
    case 'remove':
      return state.filter((_, i) => i !== action.index);
    case 'clear':
      return [];
    default:
      return state;
  }
}

export default function App() {
  const [cart, dispatch] = useReducer(cartReducer, []);
  const total = cart.reduce((sum, i) => sum + i.price, 0);
  return (
    <div>
      <button onClick={() => dispatch({ type: 'add', item: { name: 'Pen', price: 10 } })}>Add Pen ₹10</button>
      <button onClick={() => dispatch({ type: 'add', item: { name: 'Book', price: 250 } })}>Add Book ₹250</button>
      <button onClick={() => dispatch({ type: 'clear' })}>Clear</button>
      <ul>
        {cart.map((item, i) => (
          <li key={i}>{item.name} ₹{item.price} <button onClick={() => dispatch({ type: 'remove', index: i })}>x</button></li>
        ))}
      </ul>
      <b>Total: ₹{total}</b>
    </div>
  );
}

Result