Reputation: 12240
I am new to React.js Library and I was going over some of the tutorials and I came across:
this.setState
this.replaceState
The Description given is not very clear (IMO).
setState is done to 'set' the state of a value, even if its already set
in the 'getInitialState' function.
Similarly,
The replaceState() method is for when you want to clear out the values
already in state, and add new ones.
I tried this.setState({data: someArray});
followed by this.replaceState({test: someArray});
and then console.logged them and I found that state
now had both data
and test
.
Then, I tried this.setState({data: someArray});
followed by this.setState({test: someArray});
and then console.logged them and I found that state
again had both data
and test
.
So, what exactly is the difference between the two ?
Upvotes: 103
Views: 89027
Reputation: 25
Since replaceState
is now deprecated, here is a very simple workaround. Though it is probably quite seldom that you would / should resort to needing this.
To remove the state:
for (const old_key of Object.keys(this.state))
this.setState({ [old_key]: undefined });
Or, alternatively, if you don't want to have multiple calls to setState
const new_state = {};
for (const old_key of Object.keys(this.state))
new_state[old_key] = undefined;
this.setState(new_state);
Essentially, all previous keys in the state now return undefined
, which can very easily be filtered with an if
statement:
if (this.state.some_old_key) {
// work with key
} else {
// key is undefined (has been removed)
}
if ( ! this.state.some_old_key) {
// key is undefined (has been removed)
} else {
// work with key
}
In JSX:
render() {
return <div>
{ this.state.some_old_key ? "The state remains" : "The state is gone" }
</div>
}
Finally, to "replace" the state, simply combine the new state object with a copy of the old state that has been undefined
, and set it as state:
const new_state = {new_key1: "value1", new_key2: "value2"};
const state = this.state;
for (const old_key of Object.keys(state))
state[old_key] = undefined;
for (const new_key of Object.keys(new_state))
state[new_key] = new_state[new_key];
this.setState(state);
Upvotes: 2
Reputation: 3556
According to the docs, replaceState
might get deprecated:
This method is not available on ES6 class components that extend React.Component. It may be removed entirely in a future version of React.
Upvotes: 14
Reputation: 1714
Definition by example:
// let's say that this.state is {foo: 42}
this.setState({bar: 117})
// this.state is now {foo: 42, bar: 117}
this.setState({foo: 43})
// this.state is now {foo: 43, bar: 117}
this.replaceState({baz: "hello"})
// this.state. is now {baz: "hello"}
Take note of this from the docs, though:
setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.
Same goes for replaceState()
Upvotes: 49
Reputation: 86220
With setState
the current and previous states are merged. With replaceState
, it throws out the current state, and replaces it with only what you provide. Usually setState
is used unless you really need to remove keys for some reason; but setting them to false/null is usually a more explicit tactic.
While it's possible it could change; replaceState currently uses the object passed as the state, i.e. replaceState(x)
, and once it's set this.state === x
. This is a little lighter than setState
, so it could be used as an optimization if thousands of components are setting their states frequently.
I asserted this with this test case.
If your current state is {a: 1}
, and you call this.setState({b: 2})
; when the state is applied, it will be {a: 1, b: 2}
. If you called this.replaceState({b: 2})
your state would be {b: 2}
.
Side note: State isn't set instantly, so don't do this.setState({b: 1}); console.log(this.state)
when testing.
Upvotes: 153