如何改变`this.state`然后立即调用`setState`中断?

时间:2015-08-04 03:18:59

标签: javascript reactjs

said that反应组件的状态应该被视为不可变的,即使你立即调用this.state,变异setState也容易出错。也就是说,

// #1: bad...
this.state.items.push("New item");
this.setState({items: this.state.items});

// #2: good...
this.setState({items: this.state.items.concat(["New item"])});

有人可以详细说明导致上述第一版失败的原因是什么?

1 个答案:

答案 0 :(得分:4)

当您使用新值调用setState时,React中的某些组件可以将新状态与先前状态进行比较,以检测性能增强的更改(请参阅此处:https://facebook.github.io/react/docs/advanced-performance.html)。该方法称为shouldComponentUpdate,并接收下一个道具和状态以进行比较。一些框架如OmniscientOm使用此功能。

在你的第一个例子中,你已经改变了状态(对象和数组在JS中是引用的),因此调用setState可能是一个无操作(因为状态已经相同)。您的组件可能无法自动重新渲染。

以下是一个例子:

// Let's assume that `this.state === {numbers: [1]};` at the start
this.state.numbers.push(2);

// Oops - we just changed this.state directly,
// so now this.state === `{numbers: [1, 2]}`

// Now, react might compare the old this.state (which has been modified to [1, 2]) 
// to the object you're passing in (which is also [1, 2]).
// This might be a no-op.
this.setState({numbers: this.state.numbers});

在第二个例子中,MDN说“concat()方法返回一个 new 数组,包含......”,即 - 你没有修改原文,你要返回一个<完全强大>新阵列。在第一个示例中,.push 编辑现有数组

因为它是一个新数组,所以比较将始终按预期运行。