3

How can I clone a react state from one to another without modifying the original state?

What I am trying to do is I want to change the state of the original state when I filter data and on reset I want to replace it with the copy of the original state.

I have tried using myArray.slice(); this works.. but when I make changes it is still rewriting my state.

How can I do this issue? is it possible?

Thanks in advance.

2
  • you can maintain two states, one original and modified, initially both are same and after any operation you have to update modified one, on reset you can easily update modified with original Commented Jun 13, 2019 at 8:26
  • You need Object.assign for this - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Jun 13, 2019 at 8:42

1 Answer 1

11

Solution

const arr = [{a: 1}]
const copy = arr.map(item => ({...item})) 

Explanation:

it sounds like a reference problem. ( shallow copy vs deep clone )

first of all, let's see how references work.

const arr = [{a: 1}]
const copy = arr // we assign copy as refernce to arr

copy.push({b:2}) // push item to copy array.
console.log(arr) // [{a: 1}, {b: 2}]
console.log(copy) // [{a: 1}, {b: 2}]

ok so we want to clone the array, but we want to create a new array (shallow copy).

const arr = [{a: 1}]
const copy = Array.from(arr) // return shallow-copied, [ref][1]

copy.push({b:2})
console.log(arr) // [{a: 1}]
console.log(copy) // [{a: 1}, {b: 2}]

but the problem is Array and Object either store by reference so when you clone(shallow) the array the objects inside are store by reference. that means, even you clone the array and create a new array, the objects inside copy with the same reference.

let's look on example.

const arr = [{a: 1}]
const copy = Array.from(arr)

copy.push({b:2})
copy[0].a = 3
console.log(arr) // [{a: 3}]
console.log(copy) // [{a: 3}, {b: 2}]

You can see it's not the same array, but the objects are the same ( by reference )

so you need deep copy and not shallow, you can read about that here

You can use lodash to deep clone, deepClone method.

or you can use ES6

const arr = [{a: 1}]
const copy = arr.map(item => ({...item})) // ES5: arr.map(item => object.assign({}, item))
Sign up to request clarification or add additional context in comments.

2 Comments

I've tried "Array.from (arr)" but it doesn't work for me, the reference still the same and modifying the variable mutate the state , but the ES6 syntax worked (Tried in Preact).
I thought that the Array.from() method was the way to go? It purports to create a new instance of the array passed to it. I have had nothing but issues with state bleeding into other state vars with Array.from() leaking to other state vars created from the same list. I will be trying to use Array.prototype.map() and see if this corrects my issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.