PassFront
  1. PassFront
  2. База знаний
  3. Хуки

Зачем нужен hook useLayoutEffect?

Хуки

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

Место в конвейере

рендер → коммит в DOM → useLayoutEffect → отрисовка кадра → useEffect

useLayoutEffect выполняется синхронно после изменения DOM, но до показа; useEffect — после показа.

Классическая задача: измерить и поправить

const Dropdown = ({ anchorRef }) => {
  const [coords, setCoords] = useState(null);

  useLayoutEffect(() => {
    const rect = anchorRef.current.getBoundingClientRect();
    const fitsBelow = rect.bottom + MENU_HEIGHT < window.innerHeight;
    setCoords({ top: fitsBelow ? rect.bottom : rect.top - MENU_HEIGHT });
  }, [anchorRef]);

  if (!coords) return null;
  return <ul style={coords}>...</ul>;
};

С useEffect меню на один кадр отрисовалось бы не в том месте и «прыгнуло» — мигание. useLayoutEffect выполняет измерение и setState до отрисовки: пользователь сразу видит правильную позицию.

Типичные применения

  • Позиционирование тултипов, поповеров, дропдаунов.
  • Измерение размеров под условный рендеринг (влезает/не влезает).
  • Синхронное восстановление позиции скролла.
  • Императивные анимации, стартующие с точного начального состояния.

Почему не использовать всегда

Он блокирует отрисовку: тяжёлая работа в нём — замороженный интерфейс. Правило: по умолчанию useEffect; useLayoutEffect — только при видимых глазом миганиях/прыжкам вёрстки. При SSR на сервере не выполняется (до React 19 React об этом предупреждал, в 19-й версии предупреждение убрали).

Коротко для собеседования

useLayoutEffect выполняется синхронно после коммита DOM, но до отрисовки кадра — для «измерить и поправить» сценариев: позиционирование поповеров, скролл, предотвращение мигания. Блокирует отрисовку, поэтому дефолт — useEffect, а layout-версия — точечно.

Другие вопросы раздела