React recommends not mutating state directly because doing so can break how React detects and responds to changes — which can lead to bugs, unexpected behavior, and UI not updating properly.
Let’s break it down 👇
🧠 1. React’s rendering depends on immutability
React relies on state comparisons (especially in functional components with hooks) to decide whether it needs to re-render the component.
When you update state with setState() or useState():
- React creates a new object reference.
- It compares the old and new state (
===check). - If they differ, React re-renders the component.
🛑 If you mutate the existing state directly, the object’s reference doesn’t change — React can’t tell anything changed.
const [user, setUser] = useState({ name: "Dev", age: 22 });
// ❌ Direct mutation — React may not re-render
user.age = 23;
// ✅ Correct way
setUser({ ...user, age: 23 });
⚠️ 2. Mutating state can cause stale or inconsistent UI
If you mutate state directly, React may skip rendering updates or render with stale data because it assumes nothing changed.
Example:
const [items, setItems] = useState(["apple"]);
function addItem() {
items.push("banana"); // ❌ mutating
setItems(items); // same reference → React won’t re-render
}
✅ Fix:
setItems([...items, "banana"]);
🔁 3. Immutability makes debugging and undo/redo easier
When you treat state as immutable, each state change creates a new snapshot of your app’s data.
This makes features like undo/redo, time travel debugging (in Redux DevTools), or comparing previous vs current states trivial.
🧱 4. Mutations can cause unpredictable side effects
When multiple components share state (e.g., via Context or props), direct mutation can change data before other components expect it, breaking isolation and predictability.
✅ Summary
| Reason | Why it matters |
|---|---|
| React uses shallow comparison | Mutations break change detection |
| UI may not update | React doesn’t see the change |
| Harder to debug | No clear “before/after” state |
| Can cause side effects | Shared data changes unexpectedly |
In short:
Always treat state as immutable — never modify it directly, always create a new copy when updating.