Mutating vs Non-Mutating Array Methods in JavaScript
Understand the critical difference between mutating and non-mutating array methods. Learn which methods modify in-place and which return new arrays. Essential for React and Redux. Free reference.
Detailed Explanation
Mutating vs Non-Mutating Array Methods
Understanding which array methods mutate (modify) the original array and which return new values is essential for writing bug-free JavaScript, especially in React, Redux, and other state management systems.
Mutating Methods (Modify in Place)
These methods change the original array:
| Method | What it does |
|---|---|
push() |
Add to end |
pop() |
Remove from end |
shift() |
Remove from start |
unshift() |
Add to start |
splice() |
Add/remove at index |
sort() |
Sort in place |
reverse() |
Reverse in place |
fill() |
Fill with value |
copyWithin() |
Copy within array |
Non-Mutating Methods (Return New Values)
These methods never modify the original:
| Method | What it returns |
|---|---|
map() |
New transformed array |
filter() |
New filtered array |
slice() |
New sub-array |
concat() |
New merged array |
flat() / flatMap() |
New flattened array |
toSorted() |
New sorted array (ES2023) |
toReversed() |
New reversed array (ES2023) |
toSpliced() |
New spliced array (ES2023) |
with() |
New array with replacement (ES2023) |
reduce() |
Accumulated value |
find() / findIndex() |
Element or index |
some() / every() |
Boolean |
includes() / indexOf() |
Boolean or index |
join() |
String |
at() |
Single element |
Why It Matters in React
// BUG: mutating state directly
const [items, setItems] = useState(["a", "b", "c"]);
items.push("d"); // WRONG — mutates current state
setItems(items); // React won't re-render (same reference)
// CORRECT: return a new array
setItems([...items, "d"]); // spread
setItems(items.concat("d")); // concat
setItems(prev => [...prev, "d"]); // updater function
// Sort without mutation
setItems(items.toSorted()); // ES2023
setItems([...items].sort()); // pre-ES2023
Rule of Thumb
In functional code or React:
- Prefer non-mutating methods (
map,filter,slice,toSorted,with) - If you must use a mutating method, copy first:
[...arr].sort() - Use ES2023 methods (
toSorted,toReversed,toSpliced,with) when possible
Use Case
Understanding mutation is critical when working with React state, Redux reducers, shared data structures, or any code where multiple parts of the application reference the same array. Preferring immutable methods prevents an entire class of bugs.