React.js中的setState与replaceState


96

我是React.js库的新手,我正在浏览一些教程,发现了:

  • this.setState
  • this.replaceState

给出的说明不是很清楚(IMO)。

setState is done to 'set' the state of a value, even if its already set 
in the 'getInitialState' function.

同样,

The replaceState() method is for when you want to clear out the values 
already in state, and add new ones.

我先尝试this.setState({data: someArray});然后this.replaceState({test: someArray});再进行console.logging它们,发现state现在同时具有datatest

然后,我尝试this.setState({data: someArray});依次输入“ this.setState({test: someArray});console”和“ console.log”,发现它们state又具有datatest

那么,两者之间到底有什么区别?


1
您的第一个例子是不准确的。replaceState将删除先前的状态。您可能测试不正确。
Brigand 2014年

1
我没有在回调中寻找更改。也许这就是原因..
myusuf

Answers:


138

setState当前和以前的状态合并。使用replaceState,它将抛出当前状态,并仅用您提供的状态替换它。通常setState使用该命令,除非您出于某些原因确实需要删除密钥;但是将它们设置为false / null通常是更明确的策略。

虽然有可能改变。replaceState当前使用传递的对象作为状态,即状态,replaceState(x)一旦设置this.state === x。它比轻一些setState,因此如果成千上万的组件频繁设置其状态,则可以将其用作优化。
我在这个测试用例中断言了这一点


如果您的当前状态是{a: 1},并且您打电话this.setState({b: 2}); 当应用状态时,它将为{a: 1, b: 2}。如果你打电话,this.replaceState({b: 2})你的状态将是{b: 2}

旁注:状态不是立即设置的,因此this.setState({b: 1}); console.log(this.state)在测试时不要这样做。


1
我仍然不清楚。您能举个例子,在其中一个使用另一个来更改结果,即您指的是这种合并...
Serj Sagan

1
如何存在先前状态和当前状态,例如,我们如何访问它们?另外,我确实传递了一个对象来替换状态,但是以前的状态数据仍然存在。
myusuf 2014年

1
那么何时设置状态?就像我什么时候可以console.log它并对其进行测试?
myusuf 2014年

21
@myusuf.setState({...}, callback)
Brigand

46

通过示例定义:

// 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"}

不过请从docs中注意这一点:

setState()不会立即更改this.state,但会创建一个挂起的状态转换。调用此方法后访问this.state可能会返回现有值。

一样 replaceState()


14

根据docsreplaceState可能会被弃用:

此方法在扩展React.Component的ES6类组件上不可用。在将来的React版本中可能会完全删除它。


是否有类似的替代方法?
zero_cool,2016年

1
对于“相似”的方法,你可以使用this.setState({所有:未定义,老:未定义,键:未定义,新:值})
雷恩

@W,这是什么?该官方签名是否可以重置状态?
绿色

不,它只是将预先存在的状态显式设置为undefined,这是“ replaceState”的最终结果,而没有所有现存的键。
Wren

2

由于replaceState现已弃用,因此这是一个非常简单的解决方法。尽管您很少/应该诉诸于此。

删除状态:

for (const old_key of Object.keys(this.state))
    this.setState({ [old_key]: undefined });

或者,如果您不想多次拨打 setState

const new_state = {};
for (const old_key of Object.keys(this.state))
    new_state[old_key] = undefined;
this.setState(new_state);

从本质上讲,该状态下的所有先前键现在都将返回undefined,可以很容易地使用以下if语句对其进行过滤:

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
}

在JSX中:

render() {
    return <div>
        { this.state.some_old_key ? "The state remains" : "The state is gone" }
    </div>
}

最后,要“替换”状态,只需将新状态对象与旧状态副本合并为undefined,然后将其设置为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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.