Skip to main content

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)

javascript
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)

javascript
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

javascript
oldState === newState

It 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

javascript
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); // false

React reacts to a change in reference (address), not to identical "internal values".


What breaks on mutation

If you mutate state directly:

  1. React won't know about the change -> there will be no re-render.
  2. Predictability breaks - old versions of the state change "down the chain".
  3. React optimizations break (for example, memo, PureComponent).
  4. Debugging and "time-travel" (in devtools) become impossible, because past states are already corrupted.

Example with an array

Bad:

javascript
setItems(items.push("new")); // push mutates the array

Good:

javascript
setItems([...items, "new"]); // creates a new array

Now 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

QuestionAnswer
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
ExamplesetUser(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 ready
Premium

A concise answer to help you respond confidently on this topic during an interview.