Suggest an editImprove this articleRefine the answer for “useReducer() vs useState()”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`useReducer()`** is worth using instead of `useState()` when the update logic is complex or multi-step, the state has many interrelated pieces of data, and you need a clear structure of "actions", unlike `useState`, which fits a simple, independent piece of state. **Key point:** the reducer makes state deterministic: the same action always produces the same new state.Shown above the full answer for quick recall.Answer (EN)Image## The main difference | Hook | What for | |---|---| | `useState` | Simple, independent state (a single value, short logic) | | `useReducer` | Complex update logic, many interrelated pieces of data, a clear structure of "actions" | ## When it is worth using `useReducer()` ### 1. When the update logic is **complex or multi-step** If you have several types of changes that depend on different conditions, it makes more sense to have one centralized `reducer` instead of many `setState` calls and `if` statements. #### Example: ```javascript const [state, dispatch] = useReducer(reducer, { count: 0, step: 1 }); function reducer(state, action) { switch (action.type) { case "increment": return { ...state, count: state.count + state.step }; case "decrement": return { ...state, count: state.count - state.step }; case "setStep": return { ...state, step: action.payload }; default: return state; } } ``` Here `useReducer` is more convenient than three separate `useState` calls. ### 2. When states are **interrelated** If changing one field affects others, `useReducer` lets you manage them **in one place**, instead of in dozens of `setState` calls. #### Example: ```javascript function formReducer(state, action) { switch (action.type) { case "CHANGE_FIELD": return { ...state, [action.field]: action.value }; case "RESET": return initialForm; default: return state; } } ``` Managing a form in one reducer is simpler and more reliable than 5 separate `useState` calls. ### 3. When you need **predictable behavior** and a "Redux approach" If you want updates to be transparent, testable, and centralized (for example, like in Redux), `useReducer` does this with React's built-in tools. > "The reducer makes state deterministic: > the same action → always the same new state." ### 4. When updates depend on the previous state Instead of writing a bunch of `setState(prev => ...)` calls, the reducer handles this for you - all the logic is already inside `reducer()`. ### 5. When you want to use **context for global state** `useReducer` is very often combined with `useContext` to create **global state without Redux / Zustand**: ```javascript const StoreContext = createContext(); function StoreProvider({ children }) { const [state, dispatch] = useReducer(reducer, initialState); return <StoreContext.Provider value={{ state, dispatch }}>{children}</StoreContext.Provider>; } ``` This is a mini-Redux right inside React: clean, predictable, and with no external dependencies. ## When you do NOT need `useReducer` | Case | Better to use | |---|---| | Simple state (boolean, number, string) | `useState` | | Independent states | Several `useState` calls | | Logic is short and obvious | `useState` is simpler and more readable | | No different "action types" | `useReducer` is redundant | ## Comparison example ### With `useState` ```javascript const [count, setCount] = useState(0); const [step, setStep] = useState(1); const increment = () => setCount(prev => prev + step); ``` Simple and readable - ideal if the logic is simple. ### With `useReducer` ```javascript const [state, dispatch] = useReducer(reducer, { count: 0, step: 1 }); function reducer(state, action) { switch (action.type) { case "increment": return { ...state, count: state.count + state.step }; case "setStep": return { ...state, step: action.payload }; default: return state; } } ``` More convenient if the logic grows - for example, `decrement`, `reset`, `double`, and so on get added. ## Summary | Criterion | `useState` | `useReducer` | |---|---|---| | Simple logic | Yes | No | | Complex interrelations | No | Yes | | Many types of changes | No | Yes | | Centralized logic | No | Yes | | Easy to write | Yes | a bit more code | | Global state (via context) | possible | ideal | --- **The main rule:** > Use `useState` for simple states, > and `useReducer` when state-management logic becomes "mini business logic".For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.