React DOM元素在每次渲染时加载和卸载,而不是更新



根据React文档,当组件挂载(使用DOM元素的值)和卸载(使用null)时调用回调引用:

React将使用DOM元素调用ref回调组件挂载,并在卸载时使用null调用。

根据React调和的文档,当遇到相同类型的DOM元素时,将更新而不是替换:

当比较两个相同类型的React DOM元素时,React会查看两者的属性,保持相同的底层DOM节点,并且只有更新更改的属性。

在下面的简单代码片段中,我们记录了每次回调ref被调用时的日志:


import { useState } from "react";

export default function App() {
const [num, setNum] = useState(0);

return (
<div>
<table ref={(ref) => console.log(ref)}>
<tbody>
<tr>
<td>{num}</td>
</tr>
</tbody>
</table>
<button onClick={() => setNum((prev) => prev + 1)}>Click</button>
</div>
);
}

…令人惊讶的是,每次组件渲染时都会调用它,这表明每次组件渲染时连接的DOM节点也被卸载和加载。

为什么会这样?似乎我不理解文档,或者这里有一些我想理解的其他机制在起作用。

代码沙箱:https://codesandbox.io/s/table-mount-unmount-lr10wv

调用它是因为您将callback作为匿名函数传递,该函数将在每次更新状态时重新创建(从而强制呈现),并且当ref获得新值(使用新引用重新计算函数)时,它将触发回调执行。可以通过稳定ref回调引用来避免这种情况,如下所示:

import { useCallback, useState } from "react";
export default function App() {
const [num, setNum] = useState(0);
const refCallback = useCallback((ref) => console.log(ref), []);
return (
<div>
<table ref={refCallback}>
<tbody>
<tr>
<td>{num}</td>
</tr>
</tbody>
</table>
<button onClick={() => setNum((prev) => prev + 1)}>Click</button>
</div>
);
}

相关内容

  • 没有找到相关文章

最新更新