Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

Документы

Медиа

Назад
Вопрос про JavaScript: useLayoutEffect, React hooks, DOM, lifecycle, side effects

Когда useLayoutEffect срабатывает относительно рендера?

Вопрос проверяет понимание жизненного цикла React-компонентов и различий между хуками useEffect и useLayoutEffect, что необходимо для управления побочными эффектами, синхронизированными с обновлением DOM.

Короткий ответ

Хук useLayoutEffect срабатывает синхронно сразу после того, как React рассчитал изменения в DOM, но до того, как браузер отобразит ("нарисует") эти изменения на экране. Это позволяет выполнять операции, которые требуют измерения DOM (например, получение размеров элемента) или синхронного манипулирования DOM перед отрисовкой, чтобы избежать визуального "мерцания". В отличие от него, useEffect срабатывает асинхронно после того, как браузер выполнил отрисовку.

Длинный ответ

В React хуки useEffect и useLayoutEffect служат для выполнения побочных эффектов в функциональных компонентах, но их момент выполнения в жизненном цикле отличается, что критично для определённых сценариев.

Последовательность выполнения

Когда React обновляет компонент, процесс можно упрощённо представить так:

  1. Рендер компонента (вызов функции компонента, создание React-элементов).
  2. Сравнение нового и старого Virtual DOM (Reconciliation).
  3. Фиксация изменений в реальном DOM (Commit Phase).
  4. Вызов useLayoutEffect синхронно.
  5. Отрисовка браузером (Paint) — пиксели появляются на экране.
  6. Вызов useEffect асинхронно, после отрисовки.

Практическое применение useLayoutEffect

Основное применение useLayoutEffect — это операции, зависящие от макета DOM (layout), которые должны быть завершены до того, как пользователь увидит обновлённый интерфейс. Типичные примеры:

  • Измерение размеров или положения DOM-элемента (например, с помощью getBoundingClientRect).
  • Синхронное изменение стилей элемента (например, анимация или позиционирование тултипа), чтобы избежать визуального "дёрганья".
  • Программный скролл к определённому элементу.

Пример кода

Допустим, нам нужно измерить ширину элемента после рендера и на её основе обновить состояние:

import { useLayoutEffect, useRef, useState } from 'react';

function MeasurableComponent() {
  const ref = useRef(null);
  const [width, setWidth] = useState(0);

  useLayoutEffect(() => {
    // Этот код выполнится ДО отрисовки браузером.
    if (ref.current) {
      const measuredWidth = ref.current.getBoundingClientRect().width;
      setWidth(measuredWidth); // Синхронное обновление состояния
      // Если бы мы использовали useEffect, пользователь мог бы
      // увидеть элемент в исходном размере, а затем его изменение.
    }
  }, []); // Зависимости

  return (
    
      Ширина этого элемента: {width}px
    
  );
}

Важные замечания

Поскольку useLayoutEffect выполняется синхронно и блокирует отрисовку браузера, его следует использовать только когда это действительно необходимо для предотвращения визуальных артефактов. Для большинства побочных эффектов (запросы данных, подписки на события) достаточно асинхронного useEffect, который не блокирует отрисовку и обеспечивает лучшую производительность.

Вывод: Используйте useLayoutEffect в тех редких случаях, когда вам нужно синхронно измерить или изменить DOM сразу после обновления компонента, но до того, как браузер отобразит изменения на экране, чтобы избежать визуального мерцания. Для всех остальных эффектов предпочтительнее стандартный useEffect.

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • JavaScript

    JavaScript

  • React

    React

Ключевые слова

#useLayoutEffect

#React hooks

#DOM

#lifecycle

#side effects

Подпишись на React Developer в телеграм