Jerlam
Jerlam

Reputation: 1091

React - object.assign on state not working as expected

I want to capture the value of my state "GeoJson" at the moment M, so here is what I do:

const prevGeoJson = Object.assign({}, this.state.geoJson);
const geoJson = Object.assign({}, this.state.geoJson);
geoJson.features.push(data);

this.setState(prevState => ({
  prevGeoJson: prevGeoJson,
  geoJson: geoJson,
  currentMarker: data
}));

But then, the value of this.state.prevGeoJson has the same value than this.state.GeoJson. I guess it is a normal behaviour from Object.assign, but don't understand why, and what is the solution?

Upvotes: 1

Views: 1011

Answers (1)

TPHughes
TPHughes

Reputation: 1627

Object.assign will only do a shallow copy of an Object. This means the features array is still mutated.

See the docs here, and read where it says Warning for deep clone. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

See this answer for help in deep cloning an object: What is the most efficient way to deep clone an object in JavaScript?

The easiest way without any form of library would be like this:

const prevGeoJson = JSON.parse(JSON.stringify(this.state.geoJson));
const geoJson = JSON.parse(JSON.stringify(this.state.geoJson));
geoJson.features.push(data);

this.setState(prevState => ({
  prevGeoJson: prevGeoJson,
  geoJson: geoJson,
  currentMarker: data
}));

This will do a deep copy of the Object, by converting it to JSON string and then converting it back to a new Object.

If you don't mind using libraries then I would suggest lodash's cloneDeep method here: https://lodash.com/docs/4.17.10#cloneDeep

I hope this helps.

Upvotes: 1

Related Questions