Frontend Development › State Management & Data Fetching
Reducer
A pure function from (state, action) to the new state.
Also known as: reducer, reducers, useReducer
A reducer computes the next state from the current state plus an action: (state, action) => newState — a pure function with no side effects, no mutation, same inputs always giving same outputs. useReducer brings the pattern to components; stores scale it to apps.
function reducer(state, action) {
switch (action.type) {
case 'increment': return {...state, count: state.count + 1};
default: return state;
}
}
Purity buys testability (transitions unit-test without rendering), traceability (every change names its action), and tooling (time-travel, action logs). Complex state machines collapse into readable transition tables.
The classic mistakes:
- Mutation inside reducers.
state.items.push(x)mutates the previous state — breaking change detection, memoisation and time-travel. Return new objects (or use Immer-style drafting that produces them). - Actions as setters.
{type: 'SET_X', value}for every field recreates useState with ceremony. Actions should express intent and transitions ('CHECKOUT','RETRY'), grouping related updates atomically. - Business logic in components instead. Scattered
setStatechains across handlers duplicate transition logic and race. Centralise multi-step transitions in the reducer. - Over-sized reducers. One reducer for the whole app becomes an unreviewable switch. Split by domain; combine.
- Async in reducers. Reducers are synchronous by contract. Side effects go in effects/middleware that dispatch actions.
- Default-case drops. Swallowing unknown actions silently hides dispatched-but-unhandled intents. Return state, but log unexpected types in development.
- useState vs useReducer indecision. Related fields updating together → reducer; independent primitives → useState. The rule of thumb that ends debates.
How to use it: actions as intent, reducers as pure transitions, side effects outside. State changes become reviewable, testable, replayable — the calm centre of complex UI logic.