When would you choose useReducer over useState?
Choose useReducer when state has several related fields, or the next state depends on complex rules and actions. It centralises update logic in one pure function, which is easier to test and reason about than many scattered setters.
Explain it simply
A cart on a shopping site has items, quantities, a coupon and a total. Updating them with five different setState calls scatters the rules. A reducer is a single counter clerk: you send an action like "add item" and the clerk decides the new cart.
For a simple toggle or a text field, useState is shorter. Switch to a reducer when the update rules start to feel like a small program.
Example
function reducer(state, action) {
switch (action.type) {
case "add": return { ...state, items: [...state.items, action.item] };
case "coupon": return { ...state, coupon: action.code };
case "clear": return { items: [], coupon: null };
default: return state;
}
}
const [cart, dispatch] = useReducer(reducer, { items: [], coupon: null });
dispatch({ type: "add", item: "Notebook" });What to say in the interview
"useReducer fits state with multiple sub-values or transitions that depend on one another. The reducer is a pure function of state and action, so it is easy to unit test, and dispatch is stable. For one or two independent values useState is simpler. They are the same engine underneath."
Common mistakes
- Mutating state inside the reducer instead of returning a new object.
- Using a reducer for a single boolean.