Dan's answer gives you a practical and working syntax (do that! it's cleaner), but let's understand why.
Each spread copy is shallow, not deep. Only the first level is duplicated. For example, let's say you attempt to clone an object this way:
> let original = { someNumber: 1, someArray: [1, 2] }
> let copy = { ...original }
The objects original
and copy
are distinct. If you set properties, they won't reflect each other.
> x2.someNumber = 2
> x2.newProperty = "hello"
> console.log(x1)
{ someNumber: 1, someArray: [1,2] } // same someNumber, no newProperty!
But the value of each individual key is not duplicated, it's just a reference to the original. The someArray
property references the very same array instance in both objects. So:
> console.log(x1.someArray)
[1, 2]
> x2.someArray.push(3)
> console.log(x1.someArray)
[1, 2, 3]
Both original.someArray
and copy.someArray
are referencing the same array instance. Two references in two objects, but only one underlying array.
There's no easy, 100% foolproof way to actually clone an object, because not all objects are simple JSON-like dictionaries. But you have some options in this other answer.
When working with React and Redux, many problems can be avoided by using a library like ImmutableJS, which ensures each object is distinct and every modification produces a different object. The performance is good and the syntax more comfortable in many cases, as well.