PureComponent如何工作?

时间:2017-08-22 14:59:09

标签: javascript reactjs

我的理解是PureComponent利用shouldComponentUpdate()并对状态和道具进行浅层比较,但我创建了一个与我预期不同的小例子。

示例应用程序显示人员列表。每个列表项都可以更改其名称。尝试一下并检查代码here

在父组件中,我有一个如下所示的方法:

  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,我仍然只获得了更新重新渲染的子项的好处(I& #39;如果要检查那个,则在每个子渲染上执行控制台登录。很明显,这是React在内部做的事情,决定孩子是否应该更新,但我认为如果组件重新渲染,它将重新渲染所有内容。

1 个答案:

答案 0 :(得分:2)

  

如果该组件进行浅层比较,该组件是否不应更新?

是的。而且它没有更新。您可以看到在初始渲染后不会再次调用App组件的render()方法。这意味着浅层比较正如您所期望的那样工作并且组件(正确地)不更新。

我相信那些让你失望的部分是Person.prototype.handleSubmit()中的这一行:

this.setState({ value: '' })

oldState.value !== newState.value开始,无论Person是否为Person,都会触发修改后的PureComponent组件的重新呈现。

如果你拿出这一行,你会看到没有任何更新(你期望的行为)。

  

显然,这是React在内部做的事情,以决定孩子是否应该更新。

不,孩子正在设定自己的状态。这里的亲子关系无关紧要。 React将直接更新孩子。

将来你应该尝试隔离你的测试。这种混乱的原因是因为你依靠render()方法来确定一个孩子是否收到了新的道具。但是,当孩子收到新道具并且孩子设置新状态时,会调用render()方法。

对这种情况的一个更好的测试是检查componentWillReceiveProps()是否被调用,从而从图片中删除state

componentWillReceiveProps(newProps) {
    console.log('receiving props', newProps)
}

如果将其插入Person组件,您将看到它未被调用。正如你所期待的那样。

简而言之,React.PureComponent完全按照您的想法运作。