在render方法中创建对象是否会破坏'React.PureComponent'并在'shouldComponentUpdate'中进行渲染检查?

时间:2019-02-19 21:47:17

标签: javascript reactjs

tl; dr:当您在render方法中创建要作为props / childs传递给已渲染组件的对象/组件时,它是否通过了React.PureComponent的检查并在shouldComponentUpdate中进行了prop检查?

我看到很多与此相似的模式:

  render() {
    const commentTrigger = <Button>Comment</Button>;
    const deleteTrigger = <Button>Delete Thread</Button>;
    const someComponentProps = { 
      prop1: this.getProp1()
      prop2: this.props.prop2
    }

    return (
      <div>
        <SomeModal trigger={commentTrigger} />
        <SomeOtherModal trigger={deleteTrigger} />
        <SomeComponent {...someComponentProps}
      </div>
    )
  }

这是否会使SomeComponent中的.PureComponent检查或shouldComponentUpdate检查失败,因为每次someComponentProps都是一个不同的对象,并且特别是(假设this.getProp1()是一个新创建的对象)会单独使这些测试失败并导致props1失败。最终重新渲染组件?如果this.getProp1()只是数字怎么办?

否则,是否有充分的理由不以这种方式编写React组件? 感谢您的帮助。让我知道我是否应该改写这个问题或澄清任何事情。

2 个答案:

答案 0 :(得分:1)

PureComponent将对其道具进行浅表比较,基本上使用Object.is()比较。对于对象而言,这意味着仅当它是同一对象时才会通过,而如果它是具有相同属性的不同对象则不会通过。

因此您的前两个示例(commentTrigger和deleteTrigger)将遇到此问题。每次渲染时,它们都是全新的对象,与先前的对象无关,因此不会传递三等式。

在您的第三个示例(传播someComponentProps)中,someComponentProps是否为新对象没有区别。通过传播它,您将传递一系列单独的道具,从prop1={someComponentProps.prop1}开始,然后遍历对象的其余属性。当您不知道有多少个道具时,这是一种方便的语法。如果SomeComponent是纯组件,它将检查prop1是否更改,prop2是否更改,甚至不知道someComponentProps是否存在。

答案 1 :(得分:1)

PureComponent对props对象进行浅层相等性检查。如果下一个prop1值(由this.getProp1()创建)的===等于前一个值,prop2也是如此,则SomeComponent将不会更新。

即使道具与===不相等,也可以在shouldComponentUpdate中实施自定义检查,例如深度平等检查。