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

Ala*_* S. 1 javascript reactjs react-ref react-hooks

请在React DOCS中参考 URL。此代码的版本也在此处提供

我了解在里面Functional React Component,最好使用useCallback钩子来创建引用回调,如上面的React Docs URL中所示,但是我想了解如果使用简单的arrow function(内联函数)作为引用会发生什么情况打回来。

因此,在下面,我从上面的URL修改了代码以不使用该useCallback钩子。相反,我只是使用常规arrow function作为ref回调。此外,我添加了两个console.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);
Run Code Online (Sandbox Code Playgroud)

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

  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.
Run Code Online (Sandbox Code Playgroud)

为什么ref回调被调用3次,为什么组件在初始加载时渲染3次?

Jos*_* D. 5

为什么ref回调被调用3次,为什么组件在初始加载时渲染3次?

主要是因为在您的回调ref内部measuredRef(),您正在通过进行状态更新setHeight()

以下是分步说明:

  1. 渲染:初始渲染
  2. 设置高度 node = <h1>Hello, world</h1>:初始渲染,参考分配
  3. 渲染。:由于设置了高度而重新渲染组件

对于最后两张图片,请参阅回调ref的警告

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

  1. 设定高度。node = null:由于高度更新而为null
  2. 设定高度。 node = <h1>Hello, world</h1>:现在带有DOM元素

UPDATE(最后一次渲染#6)

  1. 最后渲染是由于#5 where node != null。因此setHeight被称为。

#4(node = null)不会引起重新渲染,仅当设置高度node != null