Що робить useInsertionEffect() (React 18)?
Що робить useInsertionEffect()
useInsertionEffect() - це спеціальний хук, який виконується ще раніше, ніж useLayoutEffect, під час «вставки» елементів у DOM (insertion phase).
Він дозволяє вставляти CSS-правила синхронно, до того як браузер виконає розкладку (layout) і фарбування (paint).
Простіше кажучи: useInsertionEffect потрібен, щоб вставити стилі (CSS, emotion, styled-components) до того, як браузер встигне «виміряти» DOM і відмалювати сторінку.
Синтаксис
useInsertionEffect(() => {
// insert or generate styles inside a <style> tag
}, [dependencies]);Схожий на useEffect і useLayoutEffect, але виконується ще раніше, буквально до будь-якого layout-ефекту.
Порядок виконання ефектів у React 18
| Етап | Що робить | Коли викликається |
|---|---|---|
| useInsertionEffect | вставка CSS або інших синхронних залежностей, що впливають на layout | до layout-ефектів |
| useLayoutEffect | вимірювання або модифікація DOM | після вставки стилів, але до paint |
| useEffect | побічні ефекти (асинхронні, що не впливають на DOM) | після paint |
Візуальна шкала:
Render → DOM inserted → [useInsertionEffect] → [useLayoutEffect] → Paint → [useEffect]Приклад (спрощений)
Уявімо, що в нас динамічна бібліотека стилів, яка під час кожного рендеру вставляє <style> із потрібними правилами.
import { useInsertionEffect } from "react";
function DynamicStyledBox({ color }) {
useInsertionEffect(() => {
const style = document.createElement("style");
style.textContent = `.dynamic-box { background-color: ${color}; }`;
document.head.appendChild(style);
return () => document.head.removeChild(style);
}, [color]);
return <div className="dynamic-box">Box</div>;
}Тут:
- React викликає useInsertionEffect до відмальовування.
- Стиль вставляється до layout, тому браузер ніколи не покаже «нефарбований» або «спалахуючий» елемент.
Навіщо потрібен (і кому)
useInsertionEffect() потрібен здебільшого бібліотекам CSS-in-JS (наприклад, emotion, styled-components v6, stitches тощо), щоб:
- Гарантувати порядок вставки стилів (наприклад, перевизначення працюють правильно);
- Уникнути «мерехтіння стилів» під час серверного рендерингу або гідратації;
- Вставляти CSS синхронно зі створенням DOM, без візуальних лагів.
Важливо
| Правило | Пояснення |
|---|---|
| Не можна працювати з DOM напряму | На момент виклику DOM ще не «готовий» для вимірювань |
| Можна лише вставляти синхронні залежності (CSS) | Усе інше - у useLayoutEffect або useEffect |
| Використовувати лише для систем вставки стилів | React попереджає, якщо використовувати у звичайних компонентах |
| Безпечно за SSR | React не викликає його на сервері (лише на клієнті) |
Порівняння з іншими ефектами
| Хук | Коли виконується | Для чого |
|---|---|---|
| useInsertionEffect | До layout | Вставка CSS, робота бібліотек стилів |
| useLayoutEffect | Після зміни DOM, до paint | Вимірювання DOM, позиціонування, синхронізація |
| useEffect | Після paint | API-запити, підписки, побічні ефекти |
Підсумок
| Питання | Відповідь |
|---|---|
| Що робить useInsertionEffect() | Дозволяє вставляти стилі (CSS) синхронно до layout, щоб уникнути візуальних артефактів |
| Коли викликається | Після оновлення DOM, але до layout-ефектів і до відмальовування |
| Коли використовувати | Лише під час створення бібліотек CSS-in-JS або вставки стилів вручну |
| Коли не використовувати | У звичайних компонентах (він блокує layout і марний для логіки) |
Резюме в один рядок:
useInsertionEffect() - це «нульовий момент» для синхронної вставки стилів перед layout, потрібен лише бібліотекам, які керують CSS динамічно.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.