提问者:小点点

反应PureComponent未实现shouldComponentUpdate


我可能遗漏了什么,但我有一个这样的组件

export default MyComponent extends React.PureComponent {
    // ...
}

当MyComponent是另一个组件渲染方法的一部分时,MyComponent每次父渲染时都会重新渲染,即使道具/状态不变。所以它似乎从React改变。组件React。PureComponent没有使组件"纯"。

我试过添加

console.info(this.shouldComponentUpdate)

在其中一个组件方法中,它说它是未定义的。不是React。PureComponent应该添加一个浅层比较的方法吗?

这已经发生在React 15.5.4和15.6.0中


共1个答案

匿名用户

PureComponent不会直接声明shouldComponentUpdate。你不能用这个来访问它。应更新组件。在React源代码中有一个shouldUpdate变量:

(下面的源代码已简化)

// default is true
var shouldUpdate = true;

if (inst.shouldComponentUpdate) {
  shouldUpdate = inst.shouldComponentUpdate(
    nextProps,
    nextState,
    nextContext,
  );
} else {
  // if it's a PureComponent
  if (this._compositeType === ReactCompositeComponentTypes.PureClass) {
    shouldUpdate =
      !shallowEqual(prevProps, nextProps) ||
      !shallowEqual(inst.state, nextState);
  }
}

// ...

if (shouldUpdate) {
  // re-render ..
}

由于它只是浅相等,下面的代码返回false,您将得到重新渲染:

const propA = { foo: 'bar' }
const nextPropA = { foo: 'bar' }

shallowEqual(propA, nextPropA) // false

所以要小心使用对象和数组。要证明PureComponent的工作原理,请参阅以下示例(v15.6):https://codepen.io/CodinCat/pen/eRdzXM?editors=1010

单击按钮不会触发Foo的渲染:

以下是PureComponent可能不适用于您的另一个示例:https://codepen.io/CodinCat/pen/QgKKLg?editors=1010

唯一的区别是

因为{foo:'bar'}!=={foo:'bar'},React将每次重新渲染。因此,直接在props中编写内联对象和数组不是一个好的实践。一个常见的错误是编写内联样式:

<Foo style={{ color: 'pink' }} />

在这种情况下,Foo将始终重新渲染,即使它是PureComponent。如果您面临此问题,您可以简单地提取对象并将其存储在某个位置,例如:

const someProp = { foo: 'bar' }

<Foo someProp={someProp} />

由于的一些Prop===的一些Prop,PureComponent的工作。