PureComponent的shallowCompare没有按预期工作

时间:2017-09-24 23:53:32

标签: reactjs react-redux

我试图通过从PureComponenet扩展来避免不必要的重新呈现子组件(Review)。

从父组件(评论)调用此组件,该组件不是PureComponent。

通过调试我发现每当其中一个评论发生变化时,所有与该产品相关的评论都会被重新渲染。显然,评论'道具得到更新,它将个人评论的相关道具传递给个别评论组件。 我也看到了这一点,

nextProps.reviewer === this.props.reviewer_info -> false
nextProps.reviewer_info = []
this.props.reviewer_info = []

我相信pureComponent使用shallowCompare,它应该在比较2个空数组时返回true,这是正确的吗?

我的父组件是否也需要是PureComponent才能阻止不必要的渲染我的子组件?这是缺少的部分吗?

我的评论组件有其他子组件,我知道也应该声明为pureComponents。 (我会更新它们,但是这会阻止Review组件实现pureComponent的好处吗?)

或者2以上不是使用pureComponent重新渲染的正确原因而我错过了其他部分?

2 个答案:

答案 0 :(得分:1)

  

我的父组件是否也需要是PureComponent才能阻止不必要的渲染我的子组件?

不,这没有必要。

  

我相信pureComponent使用shallowCompare,它应该在比较2个空数组时返回true,这是正确的吗?

不是。浅层比较使用===来比较propsstate上每个属性的旧值和新值。但正如您在浏览器控制台中看到的那样[] === []false。这是因为每个[]表达式都会创建一个与其他表达式不相等的新数组对象。

因此,属性中的简单数组或对象文字(例如<Review prop={[]}/>)将在呈现Review时触发Reviews的重新呈现,从而否定PureComponent的效果1}}。

要享受优化的行为,您需要确保每个非原始道具始终引用相同的对象实例,只要其值不会发生变化(例如,将其保留在Review中的状态)。此外,如果 进行了更改,则需要为该道具创建一个新的顶级对象,而不是就地修改现有的对象(因此不要使用{{1直接分配到prop对象属性。)immutable-js包可以对此有所帮助,但es6扩展运算符通常也可以正常工作。

  

我的评论组件有其他子组件,我知道也应该声明为pureComponents。 (我会更新它们,但这会阻止Review组件实现pureComponent的好处吗?)

它不应该影响push(除非您在Review的呈现方法中创建子项,例如Reviews,在这种情况下<Review ..>..<Child ../>..</Review>将会更改时间和触发重新渲染。)

答案 1 :(得分:0)

如果你的 prop/state 是一个数组,你也可以使用 shouldComponentUpdate()

 shouldComponentUpdate(nextProps, nextState) {
    return JSON.stringify(this.props.reviewer_info) !== JSON.stringify(nextProps.reviewer_info);
  }