Array of objects? Do not spread that.

Spread operator is widely used to create a new array without mutating the original array. Below is an example.

const numbers = [1,2,3];
const numbersCopy = [...numbers];

console.log(numbers) //[1,2,3]
console.log(numbersCopy) //[1,2,3]

console.log(numbers === numbersCopy) //false

numbersCopy[0] = 999;

console.log(numbers) //[1,2,3]
console.log(numbersCopy) //[999,2,3]

When we use the spread operator, it creates a new array. In the above example, numbers and numbersCopy are not the same array. They point to different values in memory. And hence, changing the first item in numbersCopy array, does not change the numbers array.

And that's where most articles on the internet end. However, there is a minor catch for the spread operator. And that happens when you have an array of objects instead of primitives .

This is how.

const members = [{name: 'Jack', age: 28}, {name: 'Jill', age: 31}, {name: 'Hill', age: 2000}];
const membersCopy = [...members];
membersCopy[0].name = 'Kali';

console.log(membersCopy) //[{name: 'Kali', age: 28}, {name: 'Jill', age: 31}, {name: 'Hill', age: 2000}];
console.log(members);//[{name: 'Kali', age: 28}, {name: 'Jill', age: 31}, {name: 'Hill', age: 2000}];

console.log(members === membersCopy) //false
console.log(members[0] === membersCopy[0]) //true

In the above example, the reassignment mutated the members array it was done only on the membersCopy array. That's because the spread operator only makes a shallow copy rather than a deep copy.

What's the difference?

A shallow copy creates a new array but the objects within the array are pointing to the same objects in the original array. A deep copy creates a new array with new objects in memory. That's the reason, while members === membersCopy returns false, members[0] === membersCopy[0] returns true.

So, how do we fix it?

The easiest way of doing it, is using a utility like lodash.

In case you're not using  data structures like Date, undefined, Infinity, RegExp etc, you can get away with JSON.parse(JSON.stringify(arr)) Credit.