2

I'm setting the data from api in two state variables both values are same.But when I am updating one state variable the another state variable also changing.

       Api.get("url")
          .then((response) => {
            this.setState(
              {
                deliveryInfoSection2: Object.assign({}, response.data),
                deliveryInfoSection2copy: Object.assign({}, response.data),
              }
            );

          })



    updateState() {
        try {
          newVal = { ...this.state.deliveryInfoSection2 };
          newVal.orderDetails[index].bo = value.replace(global.REG_NUMBER_ONLY, '');

    //After this state variable deliveryInfoSection2copy is also updating.
          this.setState({ deliveryInfoSection2: newVal }, () => {
            if (this.state.deliveryInfoSection2.orderDetails[index].bo != '') {

        }
        catch (e) {
          alert("error" + e)
        }

      }
AlexZvl
  • 2,092
  • 4
  • 18
  • 32
ramesh m
  • 151
  • 2
  • 13

1 Answers1

3

This is a issue with respect to shallow copy of variables while using spread operator in javascript. It has nothing to do with react's setState. The spread operator creates a shallow copy for the object.

response = {
    orderDetails: [
        {
           bo: "tempData1"
        },
        {
           bo: "tempData2"
        }
    ] 
}
deliveryInfoSection2 = Object.assign({}, response)
deliveryInfoSection2Copy = Object.assign({}, response)

//Here spread operator will create shallow copy and so, the references are copied and hence any update to one will update other.
newVar = { ...deliveryInfoSection2 }
newVar.orderDetails[0].bo = "newValue"
deliveryInfoSection2 = newVar
console.log("deliveryInfoSection2", deliveryInfoSection2)
console.log("deliveryInfoSection2Copy", deliveryInfoSection2Copy)

To fix this, you need to create a deep copy of your object.
You can use JSON.parse(JSON.stringify(object)) for the same.

response = {
    orderDetails: [
        {
            bo: "tempData1"
        },
        {
            bo: "tempData2"
        }
    ] 
}
deliveryInfoSection2 = Object.assign({}, response)
deliveryInfoSection2Copy = Object.assign({}, response)

//This will create a deep copy for the variable
newVar = JSON.parse(JSON.stringify(deliveryInfoSection2))
newVar.orderDetails[0].bo = "newValue"
deliveryInfoSection2 = newVar
console.log("deliveryInfoSection2", deliveryInfoSection2)
console.log("deliveryInfoSection2Copy", deliveryInfoSection2Copy)

Hope it helps. Revert for any doubts/confusions.

Sunil Chaudhary
  • 4,481
  • 3
  • 22
  • 41
  • 1
    Thats a good one. `Object.assign({}, response)` is also a shallow copy, so the original `response` will be also modified if you change `newVar`. – AlexZvl Apr 06 '19 at 11:05