Abdul
Abdul

Reputation: 1040

React - Change in one object reflects on another even though its not modified

I am trying to change the value for an Object reflects on another if I assign the same object to two state objects. For example service returns the data like below

formData = {
  'name':'name',
  'data':{
    'value':'value',
    'isactive':false
    }
};

I am trying to assign the same object to two different state objects

this.setState({ 
  formdata: formdata,
  initialFormData : formdata
});

If I modify anything on formdata reflects on initialFormData. I mapped formdata with form. If I modify name it should reflect only on formdata but it also modifies initialFormData but I dont want my initialFormData not to be changed bec I need to reset the whole data with the initialFormData if any one clicks on reset button.

How to achieve the same . Please help me on this . Thanks in advance

If you need more info comment below . I can provide the same.

Upvotes: 1

Views: 917

Answers (3)

xadm
xadm

Reputation: 8418

Initial setState (data from service) saves references to one (base) object. This way both values are pointers to the same data. This can be done that way (for initial render) - problem is with field handlers, mutating state methods.

Your handler by accessing this.state.formdata gets pointer to base object. Mutating this changes this object, not (as you want) value (object) stored in this.state.formdata.

let formdata = this.state.formdata; // OLD REFERENCE
formdata[field] = evt.value; // THIS WAY YOU"RE MUTATING BASE OBJECT
this.setState({ formdata: formdata }); // STILL THE SAME REFERENCE

You need to prepare a new object (deep clone) and use it in setState()

let newObj = JSON.parse(JSON.stringify( this.state.formdata ));
newObj[field] = evt.value;
this.setState({ formdata: newObj });

Deep clone is needed as your base object formData contains data object. Usual methods (assign, spread) are doing shallow copy - they will copy data reference. This way f.e. mutating data.isActive will still affect both values in state.

Read article about differences.

Upvotes: 2

Olusola Omosola
Olusola Omosola

Reputation: 905

This works. You want the form data object copied for both items in state. So this will work fine.

  let formData = {
  'name':'name',
  'data':{
  'value':'value',
  'isactive':false
 }
}; 

let State = { 

 initialFormData:Object.create(formData),
 formDat:Object.create(formData)
};

console.log(State)

Upvotes: 0

Bhojendra Rauniyar
Bhojendra Rauniyar

Reputation: 85575

I think you want like this:

// outside the class
const initialFormData = {
  // your initial data
}
// inside the class
state = {
  formData: initialFormData
}
// when you want to update with initial data
this.setState({
  formData: initialFormData
})

Upvotes: 0

Related Questions