Skip to main content

Коли варто використовувати useLayoutEffect?

Коротко: навіщо він потрібен

useLayoutEffect() - це версія useEffect(), яка виконується одразу після того, як React оновив DOM, але до того, як браузер намалював (paint) зміни на екрані.

Тобто він дає можливість:

виміряти або змінити DOM до того, як користувач його побачить.


Використовуй useLayoutEffect, коли потрібно:

1. Виміряти DOM до відмальовки

Якщо ти хочеш отримати точні розміри або позицію елемента (наприклад, для обчислення положення спливаючого вікна, тултипа, каретки тощо), використовуй useLayoutEffect, щоб браузер не встиг відмалювати "старий" стан.

javascript
function Tooltip({ text }) { const ref = useRef(null); useLayoutEffect(() => { const { width, height } = ref.current.getBoundingClientRect(); console.log("Розміри елемента до відображення:", width, height); }, []); return <div ref={ref}>{text}</div>; }

Чому не useEffect: у useEffect вимірювання відбудуться після відмальовки, і дані можуть бути вже неактуальними (або спричинять "стрибок").


2. Синхронізувати візуальний стан з DOM

Якщо ти вручну змінюєш DOM (наприклад, позиціонуєш, скролиш або застосовуєш анімацію), і не хочеш, щоб користувач бачив проміжний стан, роби це у useLayoutEffect.

javascript
useLayoutEffect(() => { elementRef.current.scrollTop = elementRef.current.scrollHeight; }, [messages]);

Таким чином скрол відбудеться до того, як контент відобразиться, і не буде візуального "стрибка".


3. Запобігти "миготінню" або "стрибку" інтерфейсу

Іноді при завантаженні компонента ти змінюєш розміри, позиції, класи тощо. Якщо зробити це через useEffect, React покаже старий UI, а потім "перебудує" - користувач побачить "спалах".

Використання useLayoutEffect вирішує це:

javascript
useLayoutEffect(() => { ref.current.style.transform = "translateY(50px)"; }, []);

Ефект застосовується до paint, і користувач одразу бачить фінальний вигляд.


4. Синхронізація анімацій

Якщо ти працюєш з бібліотеками анімацій (Framer Motion, GSAP, Anime.js тощо) і потрібно, щоб анімація стартувала у точний момент перед відмальовкою,

  • useLayoutEffect дає цю точність.
javascript
useLayoutEffect(() => { gsap.from(ref.current, { opacity: 0, y: -20, duration: 0.3 }); }, []);

5. Коли логіка залежить від негайного оновлення DOM

Іноді ти змінюєш стан, і одразу після цього маєш прочитати актуальні розміри/позиції. useEffect буде занадто пізно, тому що браузер вже "показав" старий стан.

Приклад - обчислення висоти блока при зміні стану:

javascript
useLayoutEffect(() => { const h = ref.current.offsetHeight; console.log("Актуальна висота:", h); }, [isOpen]);

Коли НЕ варто використовувати useLayoutEffect

ВипадокЧому погано
Для API-запитів, таймерів, логівБлокує відмальовку без причини
Для логіки, не пов'язаної з DOMНе має сенсу
Часто оновлюваний ефектУповільнить FPS - React чекатиме завершення кожного layout-ефекту
При SSR (Next.js та ін.)React видасть попередження: "useLayoutEffect does nothing on the server"

Ідеальне правило:

Використовуй useLayoutEffect лише для DOM-операцій, які потрібно виконати до того, як користувач побачить екран. Все інше - у useEffect.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.