为什么react setState方法是不可变的?

javascript reactjs immutability difference setstate

3233 观看

3回复

16 作者的声誉

以下来自React教程:

const squares = this.state.squares.slice();
squares[i] = 'X';
this.setState({squares: squares});

此代码更改已复制state.squares并分配给orginal state.squares。最后,这更改了原始代码state.squares,因此我认为这与如下所示的可变代码没有什么不同:

this.state.squares[i] = 'X';

有什么区别吗?

作者: Tetote 的来源 发布者: 2017 年 9 月 15 日

回应 3


0

4522 作者的声誉

您可以这样做,但不应该这样做,其原因是,如果您使用

this.state.squares[i] = 'X';

下一个将覆盖它

this.setState({squares: squares});

因此,您的应用程序将没有准确的数据。

从文档:

切勿直接更改this.state,因为setState()随后的调用可能会替换您所做的更改。将this.state视为不可变的。

https://facebook.github.io/react/docs/react-component.html#state中查看有关此内容的更多信息

作者: Jigar Shah 发布者: 2017 年 9 月 15 日

0

1567 作者的声誉

该代码是不变的,因为使用了slice()method。如果你试试:

someState = {squares: [1,2,3,4,5]}
squares = someState.squares.slice()

您将获得通过slice()method 创建的新数组。

您可以通过以下方式进行测试:

squares = someState.squares.slice()
squares2 = someState.squares
squares[0] = 9    // doesn't change someState
squares2[1] = 9   // changes someState
someState.squares // [1,9,3,4,5] - as I said

如果您有疑问this.setState({squares: squares});-是的,当然,在运行此状态后,您将拥有新状态,但实际上,该状态不是修改后的旧状态对象,而是由旧零件创建的新对象。因此,如果您尝试:

oldState = this.state
this.setState({squares: squares})

您会看到新状态将不同于保存的旧状态:

this.state == oldState //false

万一this.state.squares[i] = 'X'; oldState也会被修改,这就是我们所说的可变性。旧状态的所有复制部分都会随之变化,从而导致许多问题。

作者: Karol Selak 发布者: 2017 年 9 月 15 日

0

332 作者的声誉

我也想知道这个问题。但是我发现答案并不令人满意。所以这是我的看法

答案实际上是直接写在文档中的 http://reactjs.org/docs/state-and-lifecycle.html#do-not-modify-state-direct

所以第一个原因,setState()触发render()

第二个原因,状态更改在React中是异步的,因此当您仍然引用旧的未更改状态时,您可能有其他一些组件在后台更改状态,这会导致错误的状态值

作者: grandia 发布者: 2018 年 6 月 14 日
32x32