Sikau

React · Day 17 · about 30 min

useReducer

One place for complex state updates.

Too many setStates

A cart with add, remove, change quantity, apply coupon and clear — the update logic gets scattered across handlers. A reducer gathers it in one pure function: give it the current state and an *action*, get back the next state.

dispatch(action) → reducer → new state

import { useReducer } from "react";

function reducer(state, action) {
  switch (action.type) {
    case "add":
      return { ...state, count: state.count + action.amount };
    case "reset":
      return { ...state, count: 0 };
    default:
      throw new Error("Unknown action: " + action.type);
  }
}

export default function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });
  return (
    <div>
      <p>{state.count} plates</p>
      <button onClick={() => dispatch({ type: "add", amount: 1 })}>+1</button>
      <button onClick={() => dispatch({ type: "add", amount: 5 })}>+5</button>
      <button onClick={() => dispatch({ type: "reset" })}>Reset</button>
    </div>
  );
}
  • Reducers are easy to test: call them with a state and an action, check the result.
  • useReducer + context is a lightweight store for a whole app.
  • Libraries like Redux Toolkit and Zustand build on the same idea.

The rest of this lesson

  • Actions describe what happenedexplain
  • useState or useReducer?explain
  • Next state?predict
  • Reduce an actionpredict
  • Your turnwrite code
  • Badge quizquiz
  • What you learnedrecap

Continue this lesson free — run real code in your browser

Continue with Google

See all 24 lessons of React