State & Events
React Updating Arrays in State
Array state follows the same immutability rule. Use methods that return a new array — map, filter, concat, slice, toSorted — and avoid the ones that mutate in place: push, pop, splice, sort, reverse.
What is Updating Arrays in State in React?
Array state follows the same immutability rule. Use methods that return a new array — map, filter, concat, slice, toSorted — and avoid the ones that mutate in place: push, pop, splice, sort, reverse.
Why Updating Arrays in State matters
Lists are everywhere: todos, cart items, search results, selected filters. Mutating them is the single most common reason a React list "does not update".
Updating Arrays in State example
const [jobs, setJobs] = useState([]);
// add to the end
setJobs(prev => [...prev, newJob]);
// remove by id
setJobs(prev => prev.filter(j => j.id !== id));
// update one item
setJobs(prev => prev.map(j => (j.id === id ? { ...j, saved: true } : j)));
// insert at an index
setJobs(prev => [...prev.slice(0, i), newJob, ...prev.slice(i)]);How this works
Each expression builds a fresh array. map returns the same item reference for untouched entries, which keeps memoised children from re-rendering unnecessarily.
Mutating methods and their safe replacements
| Avoid (mutates) | Use instead |
|---|---|
| push / unshift | [...arr, item] / [item, ...arr] |
| pop / shift | arr.slice(0, -1) / arr.slice(1) |
| splice | filter, or slice + spread |
| sort / reverse | [...arr].sort() or arr.toSorted() |
| arr[i] = x | arr.map((v, idx) => idx === i ? x : v) |
Common mistakes with Updating Arrays in State
- Calling arr.sort() directly on state — sort mutates and returns the same reference.
- Using push then setJobs(jobs), which passes the identical reference.
- Rebuilding every object inside map, which breaks memoisation on unchanged rows.
React Updating Arrays in State— Interview Questions & FAQs
Why does my list not update after push?+
push mutates the existing array and returns its new length, so the reference React holds is unchanged. Use setJobs(prev => [...prev, item]) instead.
