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 a React hook that lets you manage state through a reducer function: state is not changed directly, but through an "action", similar to the Redux principle. **Key point:** `dispatch` sends an action, and `reducer(state, action)` returns the new state, unlike `useState`, which just stores a value.Shown above the full answer for quick recall.Answer (EN)Image## What `useReducer` does `useReducer` is a React hook that lets you manage state **through a reducer function**. It resembles the Redux principle: > state is not changed directly, but through an "action". ### Syntax ```javascript const [state, dispatch] = useReducer(reducer, initialState); ``` - `state` - the current state - `dispatch` - the function that sends an "action" - `reducer(state, action)` - the function that receives the current state and the "action", and **returns the new state** ### Simple example ```javascript function reducer(state, action) { switch (action.type) { case "increment": return { count: state.count + 1 }; case "decrement": return { count: state.count - 1 }; default: return state; } } function Counter() { const [state, dispatch] = useReducer(reducer, { count: 0 }); return ( <div> <p>{state.count}</p> <button onClick={() => dispatch({ type: "increment" })}>+</button> <button onClick={() => dispatch({ type: "decrement" })}>-</button> </div> ); } ``` How this works: 1. On click, React calls `dispatch({ type: "increment" })`. 2. React calls `reducer(state, action)`. 3. The reducer returns the **new state** → React re-renders the component. ## How `useReducer` differs from `useState` | Criterion | `useState` | `useReducer` | |---|---|---| | State type | Simple (single value) | Complex (object, array, update logic) | | Update | `setState(newValue)` | `dispatch({ type, payload })` | | Update logic | Directly in the component | Extracted into a separate function (`reducer`) | | When to use | Simple cases (counter, form, toggle) | When the state is complex or driven by different actions | | Good fit for | Small components | Large / complex states | | Similar to | A built-in Redux alternative | A mini-Redux inside one component | ## Comparison example ### The `useState` version ```javascript const [count, setCount] = useState(0); const increment = () => setCount(count + 1); const decrement = () => setCount(count - 1); ``` Simple, but does not scale if the logic gets complex. ### The `useReducer` version ```javascript function reducer(state, action) { switch (action.type) { case "increment": return { ...state, count: state.count + 1 }; case "decrement": return { ...state, count: state.count - 1 }; case "reset": return { ...state, count: 0 }; default: return state; } } const [state, dispatch] = useReducer(reducer, { count: 0 }); ``` Now you can manage the logic centrally - handy when there are many branches or states. ## When it is better to use `useReducer` Use `useReducer` when: 1. The state is **complex** (for example, an object with several fields). 2. The update logic **depends on different action types**. 3. Several parts of the code may **update the same state**. 4. You want to **separate the logic (reducer)** from the **UI component**. Examples: - A form with validation - A multi-step process (wizard / onboarding) - A list of items with filtering, sorting, adding, and removing ## A "form" example with `useReducer` ```javascript function formReducer(state, action) { switch (action.type) { case "changeField": return { ...state, [action.field]: action.value }; case "reset": return { name: "", email: "" }; default: return state; } } function Form() { const [form, dispatch] = useReducer(formReducer, { name: "", email: "" }); return ( <form> <input value={form.name} onChange={(e) => dispatch({ type: "changeField", field: "name", value: e.target.value }) } /> <input value={form.email} onChange={(e) => dispatch({ type: "changeField", field: "email", value: e.target.value }) } /> <button onClick={() => dispatch({ type: "reset" })}>Clear</button> </form> ); } ``` Now it is easy to extend the form - just add a new `case`. ## Summary | Question | Answer | |---|---| | What does `useReducer` do? | Manages state through a reducer function, reacting to "actions" | | How does it differ from `useState`? | `useState` just stores a value, `useReducer` manages complex logic | | When to use it? | For complex or related updates | | When not to? | For simple numbers, strings, flags - `useState` is simpler | | How is it similar to Redux? | The same "action → reducer → new state" principle, just local |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.