When state updates involve multiple fields, branching logic, or action history, useReducer centralizes transitions in a pure reducer function—similar to Redux without the boilerplate of a global store.
Shape
const [state, dispatch] = React.useReducer(reducer, initialState);
dispatch({ type: 'increment' });
Reducer rules
- Must be pure: no fetch, no mutation of arguments
- Return the next state object (or previous state if nothing changes)
- Use action types (often discriminated unions in TypeScript) for clarity
useState vs useReducer
Stick with useState for simple toggles and strings. Reach for useReducer when the next state depends on a matrix of prior state + action, or when multiple child handlers dispatch the same actions.
Self-check
- Why must reducers avoid side effects?
- What does
dispatchreturn?