Capítulo 61 de 116
useReducer(reducer, initialArg, init?) is the API reference for the pattern introduced conceptually in Ch 31: it returns [state, dispatch], where dispatch(action) hands an action object to a pure reducer(state, action) function that computes and returns the next state.
const [state, dispatch] = useReducer(reducer, initialArg, init?). reducer(state, action) must be pure and return the complete next state (not a partial patch). The optional third argument init(initialArg) lazily computes the actual initial state from initialArg, useful when computing the initial value is itself expensive and shouldn't re-run on every render.dispatch has a stable identity across re-renders, like a useState setter — safe to omit from Effect/useCallback dependency arrays without causing stale-closure bugs.dispatch calls are batched and queued the same way useState setters are (Ch 24) — several dispatches inside one event handler are processed in order against the reducer, producing one re-render, not one per dispatch.switch should be exhaustive — an unrecognized action.type reaching the default case is a real bug and should typically throw, not silently return unchanged state, so mistakes surface immediately during development.init: useReducer(reducer, initialArg, init) calls init(initialArg) only once, on mount — contrast with computing the same expensive value inline as the second argument, which (if written as a function call rather than a literal) would re-run every render.function tasksReducer(tasks, action) {
switch (action.type) {
case 'added': return [...tasks, { id: action.id, text: action.text }];
case 'deleted': return tasks.filter(t => t.id !== action.id);
default: throw Error('Unknown action: ' + action.type);
}
}
const [tasks, dispatch] = useReducer(tasksReducer, []);
dispatch({ type: 'added', id: nextId(), text });
[state, dispatch] shape, with a pure reducer function handling every recognized action type and throwing on unrecognized ones.useReducer when related state updates would otherwise be scattered across many useState calls and handlers — it centralizes the "how state changes" logic in one testable function.init argument (not an inline function call in the second argument slot) for expensive initial-state computation.dispatch's stable identity is a genuine (not incidental) guarantee — rely on omitting it from dependency arrays.dispatch follows.