[英]How can mutating `this.state` and then immediately calling `setState` break?
据说应该将React组件的状态视为不可变的,并且即使立即调用setState
, this.state
进行this.state
是容易出错的。 那是,
// #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"])});
有人可以详细说明导致上述第一个版本失败的确切原因吗?
当您使用新值调用setState
时,React中的某些组件可以将新状态与先前状态进行比较,以检测更改以提高性能(请参见此处: https : //facebook.github.io/react/docs/advanced-performance。 html )。 该方法称为shouldComponentUpdate
,并接收下一个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()方法返回一个包含...的新数组”,即—您没有修改原始数组,而是完全返回了一个新数组。 在第一个示例中,.push 编辑现有数组 。
因为它是一个新数组,所以比较将始终按预期进行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.