Immutable State Updates in React: Best Practices for Complex Objects
Got it — here’s your React useState Immutable Update Cheatsheet condensed into a single interview-friendly page:
React useState Immutable Update Cheatsheet
1. Rule #1 — Immutability
Never mutate the existing state object.
Always return a new reference so React knows to re-render.
2. Shallow Updates (One-Level Objects)
jsx
コピーする
編集する
const [user, setUser] = useState({ name: 'Alice', age: 25 });
setUser(prev => ({
...prev,
name: 'Bob'// update one property
}));
3. Deep Updates (Nested Objects)
jsx
コピーする
編集する
const [person, setPerson] = useState({
name: 'Niki',
artwork: { title: 'Blue Nana', city: 'Hamburg' }
});
setPerson(prev => ({
...prev,
artwork: { ...prev.artwork, city: 'New Delhi' }
}));
Repeat shallow-copy for each nested level you modify.
4. Easier Deep Updates with Immer
jsx
コピーする
編集する
importproducefrom'immer';
setUser(prev =>
produce(prev, draft => {
draft.details.city ='NewCity';
})
);
Write like you’re mutating — Immer returns a newimmutable object.
5. Why Use Functional Updates?
React updates state asynchronously.
setState(prev => ...) ensures you always work with the latest value.
jsx
コピーする
編集する
setCounter(prev => prev +1);
6. Key Differences from Class setState
Class setState merges objects automatically.
useState replaces the whole state — you must manually merge.
7. Interview Pro Tips
Always spread (...) old state into the new one before overriding properties.
For arrays, use [...prev, newItem] or .map() for updates.
For very complex state, use useReducer or Immer.
Quick Summary Table
Situation Example
Shallow object update { ...prev, key: value }
Nested object update { ...prev, nested: { ...prev.nested, key: value } }
Array add item [...prev, newItem]
Array remove/filter item prev.filter(item => item.id !== id)
Array update item prev.map(item => item.id === id ? {...item, key: v} : item)
Complex deep updates immer or useReducer