我发现了很多关于PureComponents的帖子,但我想知道以下几点:
如果有反应。PureComponent或shouldComponentUpdate只进行肤浅的比较——这是否意味着,如果我通过道具传递一个对象,或者将我的状态与下一个状态(这是一个对象)进行比较,那么即使该对象的属性发生了更改,也总是会导致false(因为它仍然指向同一个对象,并且没有对属性进行比较),因此,我的组件不会重新渲染吗?
是的,由于对象是相同的,所以当未调用render时,您可能会遇到这种情况。甚至官方文档也建议不要将对象值传递到PureComponent
。
仅当您希望有简单的道具和状态时才扩展PureComponent,或者当您知道深层数据结构已更改时才使用forceUpdate()。或者,考虑使用不可变对象来促进嵌套数据的快速比较。
但一旦您避免对传递给父组件中的props
的对象进行变异,这将起作用。
如果你按照redux的减速器做的方式(一旦里面的任何东西被改变,返回新对象),你会没事的。
但由于它需要任何人的额外关注,所以更安全的做法是避免传递对象,并分解独立传递的基本值列表中的所有数据
[UPD]让我们看看父组件代码的几个例子:
此处MyPure将始终重新渲染,因为每次传递的对象不同:
render() {
let childData = {....};
....
return (
....
<MyPure data={childData} />
这里的MyPure
将永远不会重新渲染,因为this.childData
是浅层相同的:
changeChild = () => {
this.childData.a++;
}
render() {
....
return (
....
<MyPure data={this.childData} />
这将工作得很好,因为我们更新不同的对象后,才更新内部的东西:
changeChild = () => {
this.setState(oldState => ({
childData: {
...oldState.childData,
a: oldState.childData.a + 1
}
}));
}
render() {
....
return (
....
<MyPure data={this.state.childData} />
因此,我们需要遵循的限制很少:1。不要在render()
(通过调用分离方法显式或隐式)2中构造数据属性。不要改变对象数据属性
浅层比较将是对象内第一级属性的比较。对于state,它不应该是同一个对象,因为您应该始终使用新对象调用setState。不应直接改变现有状态。