foundation
Reducers
Write pure state transitions that return the next state from previous state and action.
Reducers are pure functions `(state, action) => nextState`. No network, no `Date.now()`, no mutating arguments. Combined reducers partition state by slice; each slice owns its subtree.
function todosReducer(state = [], action) {
switch (action.type) {
case 'todos/added':
return [...state, action.payload];
default:
return state;
}
}
With Immer inside `createSlice`, you write mutable-looking updates that produce immutable snapshots. Return `state` unchanged for unknown actions to preserve reference stability.
The trade-off is pure, testable transitions versus verbosity; Immer trades some purity visibility for ergonomics.
On interviews: prove purity — same inputs always same output; explain default branch returning previous state.
Common pitfalls: side effects inside reducers, shared mutable initial state objects, and cross-slice writes that break modularity.
Checklist:
- Pure transitions only.
- One reducer per slice domain.
- Default case returns previous state.
- Immer for nested updates in RTK.