Updating State and Immutable Updates0%

Updating State and Immutable Updates

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

Updating State and Immutable Updates

1. The Rule of Immutability

In React, state should be treated as immutable (read-only). You must never modify existing state objects or arrays directly in place. Instead, always replace them with a fresh copy containing the desired changes.

JSX
// ❌ Direct Mutation: FORBIDDEN!
const [user, setUser] = useState({ name: 'Rohit', age: 24 });
user.age = 25; // Direct mutation does NOT change object reference!
setUser(user); // React sees same reference (Object.is) -> NO RE-RENDER!
 
// ✅ Immutable Update: Create a new object copy
setUser({
...user, // Copy existing properties using object spread
age: 25 // Overwrite specific property
});

Because React uses reference equality (Object.is) to detect state changes, mutating an existing object or array in place preserves the same memory address. React assumes nothing has changed and bails out of re-rendering.

2. Functional State Updates (Updater Functions)

State updates are batched and asynchronous. If your new state depends on the immediately preceding state, you should pass a callback function to your state setter instead of a raw value:

JSX
const [count, setCount] = useState(0);
 
function handleMultipleIncrements() {
// ❌ Problematic: All three calls read 'count' as 0 in the current closure!
// setCount(count + 1); // 0 + 1 = 1
// setCount(count + 1); // 0 + 1 = 1
// setCount(count + 1); // 0 + 1 = 1
// Result: count becomes 1, NOT 3!
 
// ✅ Correct: Functional updates guarantee access to the latest pending state
setCount(prevCount => prevCount + 1);
setCount(prevCount => prevCount + 1);
setCount(prevCount => prevCount + 1);
// Result: count correctly becomes 3!
}

3. Immutably Updating Arrays in State

Arrays in JavaScript are reference types. When adding, removing, or modifying array elements in state, use non-mutating array methods:

Action❌ Mutating (Avoid)✅ Immutable (Preferred)
Add itemarr.push(item), arr.unshift(item)[...arr, item] or [item, ...arr]
Remove itemarr.splice(index, 1), arr.pop()arr.filter(item => item.id !== id)
Update itemarr[index] = newValuearr.map(item => item.id === id ? { ...item, ...newValue } : item)
Sort / Reversearr.sort(), arr.reverse()[...arr].sort(), [...arr].reverse()

Concrete Array Update Examples:

JSX
const [todos, setTodos] = useState([
{ id: 1, text: 'Master React JSX', completed: true },
{ id: 2, text: 'Learn useState Hook', completed: false }
]);
 
// 1. Adding a new todo:
const addTodo = (newText) => {
const newTodo = { id: Date.now(), text: newText, completed: false };
setTodos(prev => [...prev, newTodo]);
};
 
// 2. Toggling completion status:
const toggleTodo = (id) => {
setTodos(prev => prev.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
));
};
 
// 3. Deleting a todo:
const deleteTodo = (id) => {
setTodos(prev => prev.filter(todo => todo.id !== id));
};

4. Immutably Updating Nested Objects

When updating nested objects, remember that the object spread operator (...) only performs a shallow copy. Nested objects must be explicitly copied at every level of depth:

JSX
const [student, setStudent] = useState({
name: 'Kavita',
contact: {
email: 'kavita@example.com',
city: 'New Delhi'
}
});
 
// Updating nested city property immutably:
setStudent(prev => ({
...prev,
contact: {
...prev.contact,
city: 'Bengaluru'
}
}));

Interactive Quiz

Practice Quiz

Question 1
Why does direct mutation of an object in React state (e.g. user.name = 'New'; setUser(user);) often fail to trigger a re-render?
Question 2
When should you pass a callback function (e.g. setCount(prev => prev + 1)) to a state setter?
Question 3
Which array method is recommended for removing an item from state without mutating the original array?
Question 4
How do you add an item to the end of an array stored in state using the spread operator?
Question 5
What is a key limitation of the spread operator (...) when copying objects with nested properties?
Next Lesson

Lifting State Up Between Siblings

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext