如何防止组件重新渲染? (与 MWE)

时间:2021-02-21 18:58:00

标签: javascript reactjs canvas react-hooks components

当组件的 props 更改时,如何防止组件重新渲染?

Code sandbox link/minimal working example。将光标移到 Canvas 上,可以看到控制台记录了许多 "Canvas re-rendered" 消息。

在顶层,我将 const 函数作为处理程序传递给 CanvasonMouseMoveHandler 更新 App 的状态,以便它可以更新 Details 组件:

<div className="App">
  <Canvas onMouseMoveHandler={onMouseMoveHandler} />
  <Details passedProp={getValue} />
</div>

我需要它以便 Canvas 不会重新呈现,因为其中的 HTML canvas 元素具有用户绘制的线条。我该怎么做?

我原以为使用 React.memo 会使它成为一个纯组件,这样它就不会被重新渲染。

我是 React 的初学者,如果我没有想到正确的代码结构,请告诉我如何修复。

3 个答案:

答案 0 :(得分:0)

如果您将 onMouseMoveHandler 包装在应该解决它的 useCallback 中。问题在于,当状态发生变化时,您的 App 组件会重新呈现并且 onMouseMoveHandler 函数会获得一个新的引用。并且看到它有一个新的引用,这将导致 Canvas 也重新渲染,因为它认为这是一个 prop 更改。使用 useCallback 钩子可以保证函数引用在渲染之间保持完整。

答案 1 :(得分:0)

在您的 App.js 中,每次调用 setValue 时,您的 App 组件都会重新渲染并创建一个新的 onMouseMoveHandler 函数。 您的 Canvas 组件使用 React.memo,但由于每次重新渲染时 onMouseMoveHandler 都会获得一个新引用,因此它也会重新渲染。 为了防止出现这种情况,您必须用 onMouseMoveHandler 包裹 useCallbackuseCallback 将返回回调的记忆版本,该版本仅在依赖项之一发生更改时才会更改。 .

示例如下:

const onMouseMoveHandler = useCallback(() => {
   setValue(Math.random());
}, []);

答案 2 :(得分:0)

需要使用callBack hook,因为每次改变组件App的状态,都要重新定义函数 onMouseMoveHandler 因此值发生了变化,并且 onMouseMoveHandler 道具发生了变化,因此组件 Canvas 需要重新渲染。

您可以在此处查看修改: https://codesandbox.io/s/determined-water-72uq4?file=/src/App.js:362-380