我的理解是,PureComponent利用了shouldComponentUpdate(),并对状态和道具做了简单的比较,但我创建了一个操作与我预期不同的小示例。
示例应用程序显示了一个人的列表。每个列表项都可以更改其名称。尝试并检查代码这里。
在父组件中,我有一个如下所示的方法:
updateName(id, newName) {
const { people } = this.state
const idx = people.findIndex(person => person.id === id)
people[idx].name = newName
this.setState({ people })
} 我要传递回setState的对象具有与前一个对象相同的引用。在这种情况下,如果做的比较比较浅,这个组件不应该更新吗?
其次,另一个不清楚的部分是,我将子组件Person从PureComponent更改为component,并且我仍然只得到更新后的重新呈现的子组件的好处(如果您想检查每个子呈现,我将在每个子呈现上做一个控制台日志)。显然,这是一种反应,在内部为孩子决定是否应该更新,但我假设如果组件重新呈现,它将重新呈现所有的东西。
发布于 2017-08-22 15:22:04
如果做的是简单的比较,那么这个组件不应该更新吗?
是啊。也不是在更新。您可以看到,App组件的render()方法在初始呈现之后不会再次被调用。这意味着浅层比较正如您所期望的那样工作,并且组件(正确)没有更新。
我相信让你离开的部分是Person.prototype.handleSubmit()中的这条线
this.setState({ value: '' })由于oldState.value !== newState.value,这将触发修改后的Person组件的重新呈现,而不管Person是否为PureComponent。
如果您去掉这一行,您将看到没有任何更新(您期望的行为)。
显然,这是一种反应,在内部为孩子决定是否应该更新。
不,孩子正在设定自己的状态。父母和孩子的关系在这里无关紧要。React将直接更新孩子。
将来你应该试着隔离你的测试。之所以会出现这种混淆,是因为您依赖render()方法来确定孩子是否收到了新的道具。但是,当一个子程序接收到新的道具和一个子对象设置新的状态时,就会调用render()方法。
对这种情况的更好的测试是检查是否调用了componentWillReceiveProps(),从而从图片中删除了state:
componentWillReceiveProps(newProps) {
console.log('receiving props', newProps)
}如果将其插入到Person组件中,您将看到它没有被调用。和你期望的完全一样。
简而言之,React.PureComponent的工作方式与您所想的完全一样。
https://stackoverflow.com/questions/45821086
复制相似问题