What is state immutability?
What is state immutability
Immutability is the principle where objects or arrays are not changed directly, but changing them creates a new copy with the needed changes.
In other words: instead of "fixing the old one", we create a "new one with changes".
Example without immutability (bad)
const [user, setUser] = useState({ name: "Alex", age: 25 });
// mutating the object directly
user.age = 26;
setUser(user);Here you changed the same object in memory without creating a new one. React won't notice the difference, because the reference to the object stayed the same. -> No re-render will happen.
Example with immutability (correct)
setUser(prev => ({ ...prev, age: 26 }));Now React sees that user points to a new object in memory
and understands that the state has changed -> triggers a re-render.
Why React requires immutable updates
Because React doesn't compare the content of objects - it compares references.
React works on the principle of shallow compare
oldState === newStateIt doesn't look inside objects and arrays. If the reference stayed the same, React decides that nothing has changed. If the reference is new, React considers that the UI needs to be updated.
Example: reference and value
const a = { x: 1 };
const b = a; // reference to the same object
const c = { x: 1 }; // a new object with the same content
console.log(a === b); // true
console.log(a === c); // falseReact reacts to a change in reference (address), not to identical "internal values".
What breaks on mutation
If you mutate state directly:
- React won't know about the change -> there will be no re-render.
- Predictability breaks - old versions of the state change "down the chain".
- React optimizations break (for example,
memo,PureComponent). - Debugging and "time-travel" (in devtools) become impossible, because past states are already corrupted.
Example with an array
Bad:
setItems(items.push("new")); // push mutates the arrayGood:
setItems([...items, "new"]); // creates a new arrayNow React will see that the reference to the array has changed, and will update the component.
When this is especially important
Immutability is needed:
- when working with objects and arrays (complex state);
- in Redux, Zustand, Jotai, Recoil - all of these libraries rely on it;
- when using memoization (
React.memo,useMemo,useCallback); - when optimizing re-renders.
Under the hood: why this is convenient for React
Immutability gives React the ability to:
- quickly understand which parts of the tree have changed (through reference comparison);
- efficiently perform reconciliation;
- safely "rewind" state in devtools;
- simplify optimizations (
shouldComponentUpdate,React.memo,useMemo, etc.).
Summary
| Question | Answer |
|---|---|
| What is immutability? | Data isn't changed directly, it's replaced with a new copy |
| Why does React require it? | React compares references, not the content of objects |
| What happens on mutation? | React won't notice the change and won't re-render the component |
| How to update correctly? | Create a new object/array with the changes |
| Example | setUser(prev => ({ ...prev, name: "Tim" })) |
A simple analogy
Mutation is "repainting the old picture over the old paint". Immutability is "making a new copy of the picture with changes".
React only sees the new picture, so it understands the screen needs to be updated.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.