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"])});
有人可以详细说明导致上述第一版失败的原因是什么?
答案 0 :(得分:4)
当您使用新值调用setState
时,React中的某些组件可以将新状态与先前状态进行比较,以检测性能增强的更改(请参阅此处:https://facebook.github.io/react/docs/advanced-performance.html)。该方法称为shouldComponentUpdate
,并接收下一个道具和状态以进行比较。一些框架如Omniscient和Om使用此功能。
在你的第一个例子中,你已经改变了状态(对象和数组在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 编辑现有数组。
因为它是一个新数组,所以比较将始终按预期运行。