Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Коли варто використовувати useLayoutEffect?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`useLayoutEffect()`** - це версія `useEffect()`, яка виконується **одразу після того, як React оновив DOM**, але **до того, як браузер намалював (paint)** зміни на екрані. **Ключове:** використовуй його лише для DOM-операцій, які потрібно виконати до того, як користувач побачить екран, все інше - у `useEffect`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Коротко: навіщо він потрібен `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`.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.