Що робить useLayoutEffect?
Що робить useLayoutEffect()
Хук useLayoutEffect() дозволяє виконувати побічні ефекти
одразу після того, як React змінив DOM,
але до того, як браузер "показав" ці зміни користувачу.
Простіше кажучи:
useLayoutEffectвиконується між фазою "рендер" і фазою "відмальовування". Це дає тобі шанс "зловити DOM" і зробити з ним щось до того, як користувач побачить результат.
Синтаксис
javascript
useLayoutEffect(() => {
// код, який працює з DOM
return () => {
// очищення (cleanup)
};
}, [dependencies]);Різниця між useEffect і useLayoutEffect
| Властивість | useEffect | useLayoutEffect |
|---|---|---|
| Коли виконується | Після відмальовування браузером | До відмальовування |
| Чи блокує рендер | Ні | Так (виконується синхронно) |
| Чи можна читати/вимірювати DOM | Так, але вже після показу користувачу | Так, до показу (точніші вимірювання) |
| Типові задачі | Запити, підписки, логіка, що не впливає на розмітку | Вимірювання і синхронізація DOM, позиціонування, анімації |
| Частота використання | Дуже часто | Рідко (лише за потреби) |
Приклад: вимірювання DOM-елемента
javascript
import { useLayoutEffect, useRef, useState } from "react";
function Box() {
const boxRef = useRef(null);
const [width, setWidth] = useState(0);
useLayoutEffect(() => {
// Виконується до відмальовування браузера
const rect = boxRef.current.getBoundingClientRect();
setWidth(rect.width);
}, []);
return (
<div ref={boxRef} style={{ width: "50%" }}>
Ширина блоку: {width}px
</div>
);
}Тут:
useLayoutEffectвиконується до того, як браузер покаже сторінку.- Ми вимірюємо ширину блоку, поки DOM уже готовий, але ще не відображений.
- Це запобігає "миготінню" (flashing), якби ширина обчислювалася в
useEffect.
Приклад: синхронізація скролу або позиціонування
javascript
function ScrollSync({ scrollTo }) {
const ref = useRef(null);
useLayoutEffect(() => {
ref.current.scrollTop = scrollTo; // точно до відмальовування
}, [scrollTo]);
return (
<div
ref={ref}
style={{ height: 200, overflowY: "scroll", border: "1px solid gray" }}
>
<div style={{ height: 1000 }}>Контент...</div>
</div>
);
}Якби ми використовували useEffect, користувач міг би побачити "стрибок" скролу.
З useLayoutEffect усе відбудеться до показу, без артефактів.
Важливо пам'ятати
| Правило | Пояснення |
|---|---|
| Виконується синхронно після змін у DOM | Блокує відмальовування до завершення коду |
| Використовуй лише коли потрібно працювати з DOM напряму | Наприклад, вимірювання розмірів, позиціонування |
| Не використовуй для мережевих запитів або асинхронних дій | Це гальмує відмальовування сторінки |
Можна мати і useEffect, і useLayoutEffect в одному компоненті | React сам вирішує порядок (layout → paint → effect) |
Підсумкове порівняння
| Хук | Коли викликається | Для чого |
|---|---|---|
useEffect | Після того як браузер показав зміни | Побічні ефекти, що не впливають на DOM |
useLayoutEffect | До того як браузер показав зміни | Робота з DOM, вимірювання, синхронізація перед відмальовуванням |
Підсумок
| Питання | Відповідь |
|---|---|
Що робить useLayoutEffect() | Виконує код одразу після оновлення DOM, але до того, як браузер відмалює зміни |
| Коли використовувати | Коли потрібно виміряти або змінити DOM перед показом користувачу |
| Чому обережно | Він блокує відмальовування і може погіршити продуктивність, якщо використовувати без потреби |
| Приклади | Вимірювання розмірів, скрол, анімації, запобігання миготінню контенту |
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.