2

I don't know if there is a conflict in the libraries I'm using but for some reason or its, the latest react but when I'm updating an array from the state, it's mutating it even though I haven't called setState. Is there a special case for Arrays in the state that I'm not aware of?

constructor(props){
    super(props);

    this.state = {
      data: [
        { id: 1, name: 'hello' },
        { id: 2, name: 'world' },
        { id: 3, name: 'once' }
      ]
    }
}
performUpdate() {
  const { data } = this.state;

  var current_data = data.slice();

  current_data[0].name = 'helloooooo';

  console.log(data)

  // it shows data.id 1 now has name: 'helloooooo'
}

Since I made a copy of the array from state, shouldn't the state be updated only if I call

this.setState({
  data: current_data
})
Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90
fes
  • 2,465
  • 11
  • 40
  • 56
  • The point is that the `current_data` is a reference for the `data`. So, when you update the value of `current_data`, you're actually updating the value of the `data`. Read [this](https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0) – reisdev May 15 '19 at 11:23

2 Answers2

4

Since I made a copy of the array from state, shouldn't the state be updated only if I call

You made a shallow copy. This:

  current_data[0].name 

is same as saying:

this.state.data[0].name

this.state.data[0] and current_data[0] point to same object, due to shallow copy; even though slice returned new array, its elements basically point to same objects as the elements from the original array.

You maybe interested in how to immutably modify one of array elements.

Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90
2

slice performs a shallow copy of the array - meaning that only the pointers to the objects contained in the array are copied, not the objects themselves.

This means that after the slice you have two arrays pointing at the same objects. Naturally, then, changing an object in one, will change it in the other.

Instead, what you want to do is create a deep clone. You can use immutability-helper or something like Lodash to achieve this.

Kraylog
  • 7,383
  • 1
  • 24
  • 35