为什么在初始页面加载时多次调用 React Ref 回调(作为箭头函数或内联函数)?



请参考 React DOCS 中的这个 URL。此处还提供此代码的版本。

我知道在Functional React Component中,最好使用useCallback钩子来创建 ref 回调,如上面的 React Docs URL 所示,但我想了解如果将一个简单的arrow function(内联函数(用作 ref 回调会发生什么。

因此,在下面,我修改了上述 URL 中的代码以不使用useCallback钩子。相反,我只是使用常规arrow function作为 ref 回调。此外,我还添加了两个控制台.log语句。这是此 URL 上也提供的代码。

import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [height, setHeight] = useState(0);
const measuredRef = node => {
console.log("Setting height. node = ", node);
if (node !== null) {
setHeight(node.getBoundingClientRect().height);
}
};
console.log("Rendering.");
return (
<div className="App">
<h1 ref={measuredRef}>Hello, world</h1>
<h2>The above header is {Math.round(height)}px tall</h2>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

加载此应用程序时,将打印以下内容(添加编号(:

1. Rendering.
2. Setting height. node =  <h1>Hello, world</h1> 
3. Rendering.
4. Setting height. node =  null
5. Setting height. node =  <h1>Hello, world</h1>
6. Rendering.

为什么ref 回调被调用三次,为什么组件在初始加载时呈现三次?

为什么 ref 回调被调用三次,为什么组件在初始加载时呈现三次?

主要是因为在您的回调引用中,measuredRef(),您正在通过setHeight()进行状态更新。

以下是分步说明:

渲染
  1. :初始渲染
  2. 设置高度node = <h1>Hello, world</h1>:初始渲染、引用分配
  3. 渲染
  4. 由于设置的高度而重新渲染组件

对于最后两个打印,请参阅回调引用的警告:

如果 ref 回调被定义为内联函数,它将在更新期间被调用两次,首先使用 null,然后使用 DOM 元素。

  1. 设置高度。 节点 =空:由于高度更新而为空
  2. 设置高度。node = <h1>Hello, world</h1>: 现在有了 DOM 元素

更新(对于最后一个渲染 #6(:

  1. 最后一次渲染是由于 #5node != null.所以setHeight被召唤了。

#4 (node = null( 不会导致重新渲染,因为只有在node != null时才设置高度。

请参阅带有 ref 回调的警告:https://reactjs.org/docs/refs-and-the-dom.html#caveats-with-callback-refs

如果没有useCallback,则会在每次渲染时创建一个新的函数回调函数measuredRef

相关内容

  • 没有找到相关文章

最新更新