Drills Repository
26 Drills · All Belts · usereducer
useReducer Action Object Shape
Reducer actions are plain objects describing what happened, keeping that description separate from the logic that computes the next state. Here, dispatching an action with type 'deleted' and id 3 records that a deletion occurred without dictating how the reducer removes that item from state.
Reducer function signature
A reducer function receives the current state and an action object, then returns the next state React should use. This pure transformation model is the foundation of reducer-based state management.
useReducer return values
useReducer(reducer, initialState) returns an array containing the current state and a dispatch function used to send actions to the reducer. The array destructuring pattern const [state, dispatch] = useReducer(reducer, initialState) mirrors useState, but dispatch sends actions to the reducer instead of setting values directly.
Why Choose useReducer Over Scattered useState Calls?
useReducer consolidates update logic into a single reducer function, making related state transitions more organized and easier to reason about than scattered setter calls. This is especially valuable when multiple pieces of state change together in response to the same events.
Reading State Immediately After dispatch
Calling dispatch schedules a future render but does not mutate the existing state variable within the currently running event handler. React state behaves as a fixed snapshot tied to the render it was read in, so logging state.age immediately after dispatch still reads the old value.
useReducer vs useState for Complex Components
As a component grows, state updates scattered across many event handlers become difficult to track and reason about. useReducer centralizes that update logic into a single reducer function, making the component's state transitions easier to read and maintain.
useReducer Returning a Partial State Object
A reducer's returned object completely replaces the previous state rather than merging with it, unlike the automatic shallow merge that class-based setState performs. Since this reducer returns only { age: state.age + 1 } after the increment action, the existing name field is dropped from state entirely.
Calling dispatch During Component Rendering
Calling a dispatch function directly in the render body schedules a state update that causes an immediate re-render, and if that re-render also dispatches unconditionally, the cycle repeats with no natural stopping point. React eventually halts this pattern with a Too many re-renders safeguard error.
Reducer vs useState mental model
useReducer helps organize complex state logic by moving update rules into a centralized reducer function instead of scattering them across event handlers. This improves predictability and maintainability for interconnected state changes.
Omitting Dispatch From useEffect Dependencies
React guarantees that the dispatch function returned by useReducer keeps the same identity across every render of the component. Because that identity never changes, dispatch can safely be omitted from an Effect's dependency array without causing stale closures.
Reducer must return next state
Reducers must explicitly return the next state from every branch. Omitting return in a switch-based reducer can cause fallthrough into another case or produce undefined, resulting in an incorrect state update.
Reducer actions describe interactions
A type field labels which kind of interaction or event triggered the update, letting a single reducer function branch its logic accordingly. Any additional properties on the action object simply carry the extra data the reducer needs to compute the next state.