Sil Cia
Sil Cia

Reputation: 106

React, overriding current state with the original state

I am working on a billing component in a SPA using React. The user can fill out a checkout form and upon payment confirmation I want to reset the current (dirty) state, to the original (clean) state.

I'm using something like this in componentDidMount:

this.baseState = this.state; 

and later when I get my payment confirmation I go ahead and reset the state:

this.setState(this.baseState)

this works as expected, except for one part small of the state that does not get reset.

That specific part of the state looks like this originally:

this.state = {
        billing: {
            coupons: []
        }
}

Here it is after being modified:

this.state = {
        billing: {
            coupons: ["coupon1", "coupon2"]
        }
}

However, when I reset the state, I expect coupons to be an empty array, but somehow the data persists and it remains:

coupons: ["coupon1", "coupon2"]

Everything else is overridden accordingly, just this part persists. What am I missing?

Upvotes: 4

Views: 1765

Answers (2)

Gary Vernon Grubb
Gary Vernon Grubb

Reputation: 11215

It was rightly pointed out that the spread operator does not do a deep copy. So for a large state we would need to write a custom function. This should work for a simple state:

this.baseCoupons=[...this.state.billing.coupons]


this.setState({billing:{coupons:[...this.baseCoupons]}})

Upvotes: 0

Mayank Shukla
Mayank Shukla

Reputation: 104379

Its because this.baseState will have a reference of state values means this.state and this.baseState will point to same data.

One solution is put the state values in a function and call that whenever you want the initial values.

Like this:

constructor(){
    super();
    this.state = this.getInitialState()
}

getInitialState(){
    return {
        key: value
    }
}

Now when you want to reset the state call that function and get the initial state value.

this.setState(this.getInitialState())

If you want to store the state values in a variable, then deep clone it, Like this (one possible way of deep cloning):

this.baseState = JSON.parse(JSON.stringify(this.state))

Upvotes: 2

Related Questions