React.PureComponent没有实现shouldComponentUpdate

hen*_*nit 5 ecmascript-6 reactjs

我可能会缺少一些东西,但是我有一个像这样的组件

export default MyComponent extends React.PureComponent {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

如果MyComponent是另一个组件渲染方法的一部分,则即使父项/状态未更改,MyComponent也会在每次父项渲染时重新渲染。因此,似乎从更改React.ComponentReact.PureComponent并没有使组件“纯净”。

我尝试添加

console.info(this.shouldComponentUpdate)
Run Code Online (Sandbox Code Playgroud)

里面的组件方法之一,它说它是未定义的。不React.PureComponent应该添加一个浅表比较shouldComponentUpdate方法吗?

React 15.5.415.6.0现在已经发生了这种情况

Cod*_*Cat 4

PureComponent 不shouldComponentUpdate直接声明。您无法使用 来访问它this.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 ..
}
Run Code Online (Sandbox Code Playgroud)

因为它只是浅等于,所以下面的代码返回 false 并且您得到重新渲染:

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

shallowEqual(propA, nextPropA) // false
Run Code Online (Sandbox Code Playgroud)

因此,请谨慎使用对象和数组。要证明 PureComponent 有效,请参阅此示例 (v15.6):https://codepen.io/CodinCat/pen/eRdzXM?editors= 1010

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

在此输入图像描述

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

唯一的区别是<Foo someProp={{ foo: 'bar' }} />

因为{ foo: 'bar' } !== { foo: 'bar' },React 每次都会重新渲染。所以直接在 props 中写入内联对象和数组并不是一个好的做法。一个常见的错误是编写内联样式:

<Foo style={{ color: 'pink' }} />
Run Code Online (Sandbox Code Playgroud)

在这种情况下,Foo即使它是 PureComponent,也总是会重新渲染。如果您遇到此问题,您可以简单地提取对象并将其存储在某处,例如:

const someProp = { foo: 'bar' }

<Foo someProp={someProp} />
Run Code Online (Sandbox Code Playgroud)

从那时起someProp === someProp,PureComponent 就可以工作了。