Задать вопрос
@HellYeahOmg

Какой правильный порядок будет в консоли?

Объясните, пожалуйста, детально. Правильный ответ на в консоли я видел - 1, 4... - еще понятно, но почему дальше у нас сначала идет лог из рефа ребенка, а только потом из рефа родителя - непонятно. Также непонятно почему useEffect сначала срабатывает у ребенка

код
const Child = () => {
  console.log(4);

  React.useEffect(() => {
    console.log(5);
  }, []);

  return (
    <div
      ref={() => {
        console.log(6);
      }}
    >
      lorem
    </div>
  );
};

export default function App() {
  console.log(1);

  React.useEffect(() => {
    console.log(2);
  }, []);

  return (
    <div
      ref={() => {
        console.log(3);
      }}
      className="App"
    >
      <Child />
    </div>
  );
}
  • Вопрос задан
  • 176 просмотров
Подписаться 2 Сложный 4 комментария
Решения вопроса 1
Alexandroppolus
@Alexandroppolus
кодир
почему дальше у нас сначала идет лог из рефа ребенка, а только потом из рефа родителя - непонятно

назначение рефов происходит на том же этапе, что и выполнение колбэка в useLayoutEffect: синхронно сразу после того, как сформируется дерево виртуального дома, и по нему будет обновлено дерево реального дома. Все перечисленное делается в одном синхронном куске кода, без микротасков и т.д. Разумеется, до этапа отрисовки на экране.
Почему снизу вверх, то есть от чилдов к парентам? Значения рефов могут использоваться в колбэках useLayoutEffect, значит они к этому моменту должны быть готовы. Т.е. чилд должен успеть назначить реф до того, как парент попробует к нему обратиться. Распространение данных в обратную сторону, в комплект к распространению в прямую (через пропсы). Это одна из причин, могут быть и другие.

Эффекты useEffect срабатывают после отрисовки на экране, т.е. в отдельном таске. Для единообразия они тоже срабатывают в порядке от чилдов к парентам.

Указанный порядок имеет свои минусы, например https://habr.com/ru/articles/574536/ , но в целом плюсы перевешивают.

Надо заметить, что и функции очистки для useEffect и useLayoutEffect тоже вызываются сначала на чилдах, что правильно со всех сторон.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы