Hooks

useReducer for complex state

Reducer patterns, when to prefer it over useState, and testability.

intermediate All levels

useReducer centralises state transitions in a pure (state, action) => state function, dispatched via actions. Prefer it over useState when the next state depends on the previous, several values change together, or transitions are complex (wizards, editors, undo/redo).

useReducer is a vending machine: press a labelled button (action) and the mechanism (reducer) deterministically produces the next state.

Key concepts

1
Because the reducer is a pure function, it is trivially unit-testable in isolation and keeps components declarative — they dispatch intent, not mechanics.
trivially unit-testable
2
dispatch is referentially stable, so passing it down (or via context) never causes child re-renders — a nice performance property versus passing many setX callbacks.
referentially stabledispatchsetX
3
Pitfall: putting side effects inside the reducer; reducers must stay pure — do effects in useEffect or handlers. Interview angle: "useState vs useReducer?" — reducer for related/complex transitions and testability; state for simple independent values.
Pitfall:Interview angle:useEffect