如何使用React.memo防止重新渲染?

时间:2019-07-30 18:57:04

标签: reactjs

我有两个功能组件。一个保持递增的数字作为状态并显示它。它的子级是一个按钮,它接受increment函数作为道具,并在单击时调用它。

const IncrementButton = props => {
  return <button onClick={props.increment}>Increment</button>;
};

const App = () => {
  const [count, setCount] = React.useState(0);
  const increment = () => setCount(count + 1);

  return (
    <div className="App">
      <h1>{count}</h1>
      <IncrementButton increment={increment} />
    </div>
  );
};

App重新渲染时,我想避免重新渲染IncrementButton

文档建议使用React.memo来执行此操作,但是当我尝试以下示例时,它没有帮助。

const IncrementButton = React.memo(props => {
  return <button onClick={props.increment}>Increment</button>;
});

我想念什么吗?记住组件以免重新渲染的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

您遇到的问题是,每当App重新发布时,它都会创建一个全新的增量函数。因此,每次Incrementbutton渲染时,它都有一个全新的props.increment。结果,React.memo实际上并没有做任何事情,因为道具不断变化,因此无法跳过任何渲染。

此问题的解决方法是这样做,这样就不会每次都重新创建增量函数。您可以使用useCallback进行此操作,因此第一遍可能看起来像这样:

const increment = useCallback(
  () => setCount(count + 1), 
  [count]
)

这将仅创建一次增量函数,然后记忆结果,直到计数更改。不幸的是,计数是唯一真正可以改变的东西,因此我们最终不得不在大多数时间重新创建此功能。因此,我们需要进行另一个修改:setCount允许您将函数传递给它,而不是将count +1传递给setCount。该函数将使用先前的值进行调用,以便您可以基于该新值:

const increment = useCallback(
  () => setCount(oldCount => oldCount + 1),
  []
);

现在您有了一个仅创建一次的增量函数,这又使IncrementButton对其道具没有任何更改,因此React.memo可以完成其工作并跳过重新渲染。

相关问题