掌握React.Memo

来自菜鸟教程
跳转至:导航、​搜索

React.memo 为我们提供了 React 中纯组件的能力,但针对的是基于函数的组件,而不是基于类的组件。

memoization 是计算机科学术语,意思是缓存昂贵的函数调用的结果,并在参数相同时返回缓存的版本。

在反应方面:

当传递的 props 相同时,我们不希望 MyNewComponent 重新渲染。

简单的计数器示例

我在 Codesandbox 中创建了 以下示例,以帮助您巩固 React.memo 的工作原理

这是一个简单的应用程序,可以计算按钮被点击的次数。 您可以从下面的屏幕截图中看到我们在页面顶部有一个横幅。

想象一下 Banner 是一个可以有不同类型的 UI 组件,在这种情况下,您想使用 info 类型的横幅,因此您可以按如下方式创建 Banner

<Banner type="info" />

我们的 CounterComponent 看起来像这样:

class CounterComponent extends Component {
  state = { buttonPressedCount: 0 };
  render() {
    const { buttonPressedCount } = this.state;
    return (
      <div className="new-component">
        <h4>Button Pressed Count: {buttonPressedCount}</h4>
        <button
          onClick={() =>
            this.setState({ buttonPressedCount: buttonPressedCount + 1 })
          }
        >
          Increase Count
        </button>
        <Banner type="info" />
      </div>
    );
  }
}

我们的 Banner 组件如下所示:

const Banner = props => {
  const { type } = props;

  if (type === "info") {
    return <div className="info-banner">I am an info banner</div>;
  }
};

在我们的 CounterComponent 中,每次单击按钮时,我们都会增加 buttonPressedCount 变量,这会导致重新渲染,这是您所期望的。 这样做的问题是 Banner 组件也会重新渲染,即使传递给它的 props 没有改变。

为了避免这种情况,我们使用 memo ,它的作用类似于 PureComponent,因为当 props 没有改变时它会停止重新渲染。 我们更新的代码如下所示:

const Banner = memo(props => {
  const { type } = props;

  if (type === "info") {
    return <div className="info-banner">I am an info banner</div>;
  }
});

现在我们的 Banner 组件只会在 props 改变时重新渲染。

这是 React 备忘录的核心基本思想。

相等

好的,让我们更深入一点,谈谈自定义平等。 默认情况下,memo 仅对道具和道具的对象进行 shallow 比较。 您可以传递第二个参数来指示自定义相等检查:

React.memo(Component, [areEqual(prevProps, nextProps)]);

这类似于 shouldComponentUpdate 但相反,即 在 shouldComponentUpdate 中返回 true 会导致另一个渲染,而 areEqual 则相反。

想象一下,我们有一个 Person 组件接受了一个 prop 人,它是一个对象,我们可以检查 name 是否相同。

const areEqual = (prevProps, nextProps) => {
  return (prevProps.name === nextProps.name)
};
React.memo(Person, areEqual);

结论

这是对 React 的一个非常好的补充,允许我们使用函数式组件而不必担心不必要的重新渲染。 一如既往,我希望你从这篇文章中学到了一些东西!