简体   繁体   中英

setState vs replaceState in React.js

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 ?

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, ie 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) this.setState({b: 1}); console.log(this.state) when testing.

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()

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.

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM