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

В чем разница между useEffect и useLayoutEffect?

Хуки

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

useEffect

  • Выполняется асинхронно после того, как браузер отрисовал кадр.
  • Не блокирует отрисовку — пользователь сразу видит обновлённый UI.
  • Подходит для 95% случаев: запросы к серверу, подписки, логирование, работа с localStorage.

useLayoutEffect

  • Выполняется синхронно после изменения DOM, но до отрисовки кадра браузером.
  • Блокирует отрисовку: пока эффект не завершится, пользователь ничего не увидит.
  • Нужен, когда эффект читает layout (размеры, позиции элементов) и синхронно меняет DOM, иначе будет видимое «мигание».

Пример, где нужен useLayoutEffect

const Tooltip = ({ targetRef }) => {
  const [position, setPosition] = useState({ top: 0, left: 0 });

  useLayoutEffect(() => {
    const rect = targetRef.current.getBoundingClientRect();
    setPosition({ top: rect.bottom, left: rect.left });
  }, [targetRef]);

  // с useEffect тултип на один кадр отрисовался бы в точке (0, 0)
  return <div style={position}>...</div>;
};

Нюансы

  • Порядок: рендер → коммит в DOM → useLayoutEffect → отрисовка браузера → useEffect.
  • Тяжёлая логика в useLayoutEffect напрямую бьёт по отзывчивости интерфейса.
  • При SSR useLayoutEffect не выполняется на сервере (до React 19 React ещё и выдавал предупреждение, в React 19 его убрали).

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

useEffect срабатывает после отрисовки и не блокирует её; useLayoutEffect — синхронно до отрисовки. По умолчанию использовать useEffect; useLayoutEffect — только когда нужно измерить или синхронно поправить DOM до того, как пользователь увидит кадр (позиционирование, предотвращение мигания).

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