Reputation: 106
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
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
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