为什么在初始页面加载时多次调用 React Ref 回调(作为箭头函数或内联函数)?
Why is a React Ref callback (as an arrow function or inline function) called multiple times on initial page load?
请参考this URL in the React DOCS. A version of this code is also available here。
我知道在 Functional React Component
中,最好使用 useCallback
钩子来创建一个 ref 回调,如上面的 React 文档 URL 所示,但我想了解如果将简单的 arrow function
(内联函数)用作 ref 回调会发生什么。
所以,下面,我修改了上面 URL 的代码,不使用 useCallback
钩子。相反,我只是使用常规 arrow function
作为 ref 回调。此外,我添加了两个 console.log 语句。这是也可在 this 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 回调调用了三次,为什么组件在初始加载时渲染了三次?
Why is the ref callback called three times and why does the component render three times on initial load?
主要是因为在回调引用 measuredRef()
中,您正在通过 setHeight()
进行状态更新。
这里是一步一步的解释:
- 渲染:初始渲染
- 设置高度
node = <h1>Hello, world</h1>
:初始渲染,参考分配
- 正在渲染。:组件因设置高度而重新渲染
最后两张图,参考caveats of callback refs:
If the ref callback is defined as an inline function, it will get called twice during updates, first with null and then again with the DOM element.
- 设置高度。 node = null:由于高度更新
,null
- 设置高度。
node = <h1>Hello, world</h1>
:现在有DOM元素
更新(最后一次渲染 #6):
- 最后一次渲染是由于 #5
node != null
。所以 setHeight
被调用了。
即 #4 (node = null
) 不会导致重新渲染,因为高度仅在 node != null
.
时设置
查看 ref 回调的注意事项:https://reactjs.org/docs/refs-and-the-dom.html#caveats-with-callback-refs
如果没有 useCallback
,则会在每次渲染时创建一个新的函数回调函数 measuredRef
。
请参考this URL in the React DOCS. A version of this code is also available here。
我知道在 Functional React Component
中,最好使用 useCallback
钩子来创建一个 ref 回调,如上面的 React 文档 URL 所示,但我想了解如果将简单的 arrow function
(内联函数)用作 ref 回调会发生什么。
所以,下面,我修改了上面 URL 的代码,不使用 useCallback
钩子。相反,我只是使用常规 arrow function
作为 ref 回调。此外,我添加了两个 console.log 语句。这是也可在 this 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 回调调用了三次,为什么组件在初始加载时渲染了三次?
Why is the ref callback called three times and why does the component render three times on initial load?
主要是因为在回调引用 measuredRef()
中,您正在通过 setHeight()
进行状态更新。
这里是一步一步的解释:
- 渲染:初始渲染
- 设置高度
node = <h1>Hello, world</h1>
:初始渲染,参考分配 - 正在渲染。:组件因设置高度而重新渲染
最后两张图,参考caveats of callback refs:
If the ref callback is defined as an inline function, it will get called twice during updates, first with null and then again with the DOM element.
- 设置高度。 node = null:由于高度更新 ,null
- 设置高度。
node = <h1>Hello, world</h1>
:现在有DOM元素
更新(最后一次渲染 #6):
- 最后一次渲染是由于 #5
node != null
。所以setHeight
被调用了。
即 #4 (node = null
) 不会导致重新渲染,因为高度仅在 node != null
.
查看 ref 回调的注意事项:https://reactjs.org/docs/refs-and-the-dom.html#caveats-with-callback-refs
如果没有 useCallback
,则会在每次渲染时创建一个新的函数回调函数 measuredRef
。