Suggest an editImprove this articleRefine the answer for “Mutating state in a reducer”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Mutating (changing directly)** `state` in a reducer is not allowed because Redux (and React) need to see that the state has changed, and that is only possible by creating a new object. **Key point:** Redux and React compare state by reference (`===`), so mutating an object leaves the reference unchanged and the component does not update.Shown above the full answer for quick recall.Answer (EN)Image## Short answer > **You cannot mutate (change directly)** `state` in a reducer, > because Redux (and React) **need to see that the state has changed**, > and that is only possible **by creating a new object**. --- ## In detail A reducer must be a **pure function**, which means: 1. It **does not change the input data (state)**. 2. It **returns a new object** describing the new state. --- ### Example of a correct reducer ```javascript function counterReducer(state = { count: 0 }, action) { switch (action.type) { case 'INCREMENT': return { ...state, count: state.count + 1 } // create a new object default: return state } } ``` --- ### Example with mutation ```javascript function counterReducer(state = { count: 0 }, action) { switch (action.type) { case 'INCREMENT': state.count++ // mutates the object return state // returns the same object default: return state } } ``` The problem: Redux (and React) **will not understand that the state has changed**, because **the reference to the object has not changed** - `state` remains the same object in memory. --- ## Why this matters ### 1. Redux compares states by **reference** Redux (and React through `useSelector`) use a **shallow comparison (**`===`**)** to understand whether the state has changed. ```javascript oldState === newState // if true -> we do not re-render ``` If you mutated the object, the reference stays the same -> Redux thinks nothing has changed -> the component **does not update**. --- ### 2. Immutability enables "time travel" Redux DevTools can "rewind" state forward and backward, because every state is stored as a **new version of the object**. If reducers mutated `state`, old states would simply be destroyed. --- ### 3. Simple testing Pure functions are easy to test: the same input data -> always the same result. If you mutate state, the result can depend on the previous call. --- ### 4. Optimizing React components Many optimizations (for example, `React.memo`, `useSelector`, `PureComponent`) are based on **reference comparison** (`===`), not deep comparison. Immutability is what makes this possible. --- ## How to avoid mutating state Use **immutable methods**: | Operation | Mutation | Immutable | |---|---|---| | Add an element | `array.push(x)` | `[...array, x]` | | Remove an element | `array.splice(1,1)` | `array.filter((_, i) => i !== 1)` | | Change a property | `obj.key = value` | `{ ...obj, key: value }` | | Change a nested object | `state.user.name = 'Tim'` | `{ ...state, user: { ...state.user, name: 'Tim' } }` | --- ## Summary | Reason | Why you cannot mutate | |---|---| | Redux compares by reference | It will not see the change | | Time travel in DevTools | Old states would be lost | | Testing | It becomes unpredictable | | React optimizations | Will not work correctly | | The pure function principle | Determinism is broken |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.