The useReducer Hook: Predictable State Updates

useReducer is a state machine for your components, managing complex state changes predictably. Use it when state logic is complex or the next state depends on the previous one, like in a shopping cart.
Why it exists
While useState is perfect for simple state, it can become unwieldy when state logic gets complicated or when the next state depends on the previous one. useReducer provides a more structured and predictable way to manage these scenarios by centralizing all state update logic into a single function.
The mental model
Think of useReducer as a suggestion box for state changes. Instead of directly changing state from anywhere in your component, you dispatch an "action"—a note describing what you want to do, like { type: 'INCREMENT_COUNT' }. A single, dedicated "reducer" function picks up this note, reads it, and decides what the new state should be based on the old state and the action's instructions. This separates the "what happened" from the "how it's handled."
How it works
You call useReducer at the top level of your component with a reducer function and an initial state. It returns an array with two items: the current state and a dispatch function. To trigger an update, you call dispatch with an action object. React then runs your reducer, passing it the current state and the action. Your reducer must be a pure function that returns the new state without modifying the old one. React then re-renders the component with this new state.
When to use it
Use useReducer for non-trivial state logic. It shines when you have multiple state transitions that depend on each other, like in a multi-step wizard, a game, or a shopping cart. It also makes it easier to pass update logic down to child components, since you can pass the stable dispatch function instead of multiple different callback props.
When not to use it
For simple, independent state values like a boolean toggle or a single input field's value, useState is simpler and more direct. Using useReducer for these cases adds unnecessary boilerplate. If your state logic doesn't depend on the previous state, useState is usually the better choice.
One canonical example
A simple counter where state is an object: { count: 0 }. The reducer handles two action types, 'increment' and 'decrement'.
function reducer(state, action) {
if (action.type === 'increment') { return { count: state.count + 1 }; }
if (action.type === 'decrement') { return { count: state.count - 1 }; }
throw new Error('Unknown action.');
}In the component, you'd initialize it with const [state, dispatch] = useReducer(reducer, { count: 0 }); and then call dispatch({ type: 'increment' }) from a button's click handler.
Interview question
Which scenario best indicates that useReducer would be a more suitable choice than useState for managing component state?
- a.The component's state consists of a single boolean toggle.
- b.The state updates must be immediately reflected in the DOM without any batching.
- c.The state logic involves multiple interdependent transitions where the next state relies on the previous state.Correct
- d.You need to pass state values down to deeply nested child components.
Why? this is the answer
The card states useReducer is ideal "when state logic gets complicated or when the next state depends on the previous one," and for "multiple state transitions that depend on each other." For simple, independent state like a boolean toggle (Option A), useState is preferred.
Just read this? Test yourself on what you have been reading.
Read the original → react.dev
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on react — each one lists the topics its interview covers.
See open roles