Почему обратный вызов React Ref (в виде функции стрелки или встроенной функции) вызывается несколько раз при начальной загрузке страницы? - PullRequest
1 голос
/ 27 сентября 2019

Пожалуйста, обратитесь к этому URL в React DOCS.Также доступна версия этого кода здесь .

Я понимаю, что внутри Functional React Component предпочтительно использовать хук useCallback для создания обратного вызова ref, как показано наРеагируйте на URL документа выше, но я хотел понять, что произойдет, если вместо этого в качестве обратного вызова ref будет использоваться простая arrow function (встроенная функция).

Итак, ниже, я изменил код изURL выше, чтобы не использовать хук useCallback.Вместо этого я просто использую обычный arrow function в качестве обратного вызова.Кроме того, я добавил два оператора 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);

При загрузке этого приложения печатаются следующие данные (с добавленной нумерацией):

  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 вызывается три раза и почему компонент рендерит три раза при начальной загрузке?

Ответы [ 2 ]

5 голосов
/ 27 сентября 2019

Почему обратный вызов ref вызывается три раза и почему компонент визуализируется три раза при начальной загрузке?

В основном потому, что внутри вашего обратного вызова ref, measuredRef(), вы делаетеобновление состояния через setHeight().

Пошаговое объяснение:

  1. Рендеринг : Первоначальный рендеринг
  2. Высота установки node = <h1>Hello, world</h1>: начальный рендеринг, присвоение ссылки
  3. рендеринг. : повторный рендеринг компонента из-за установленной высоты

для последнегодве распечатки, см. предостережения об обратном вызове refs :

Если обратный вызов ref определен как встроенная функция, он будет вызываться дважды во время обновлений, сначала с нулем, а затем сновас элементом DOM.

Настройка высоты.node = null : null из-за обновления высоты Установка высоты. node = <h1>Hello, world</h1>: теперь с элементом DOM

UPDATE (дляпоследний рендер # 6) :

Последний рендер был из-за # 5, где node != null.Таким образом, setHeight был вызван.

т.е. # 4 (node = null) не вызывает повторную визуализацию, поскольку высота устанавливается только в том случае, если node != null.

0 голосов
/ 28 сентября 2019

См. Предостережение с обратными вызовами ref: https://reactjs.org/docs/refs-and-the-dom.html#caveats-with-callback-refs

Без useCallback новая функция обратного вызова функции measuredRef создается при каждом рендеринге.

...