Skip to main content

Що робить хук useInsertionEffect()?

Коротко: що робить useInsertionEffect()

useInsertionEffect() - це хук, який виконується синхронно перед тим, як браузер застосує стилі та виконає layout, тобто ще раніше, ніж useLayoutEffect().

Він потрібен, щоб бібліотеки могли:

  • вставити CSS-правила у DOM до того, як браузер намалює сторінку;
  • уникнути «мерехтіння» стилів (FOUC) під час динамічної генерації CSS;
  • гарантувати узгодженість стилів за concurrent rendering (React 18).

Синтаксис

javascript
useInsertionEffect(() => { // synchronous insertion of styles or other side effects, before layout }, [deps]);

За інтерфейсом він схожий на useEffect і useLayoutEffect, але виконується раніше за всі ефекти React, буквально до того, як браузер відмалює екран.


1. Навіщо він потрібен (і кому)

До React 18 бібліотеки для CSS-in-JS (наприклад, Emotion, styled-components, JSS):

  • генерували класи і вставляли стилі в
  • використовували для цього useLayoutEffect().

Проблема:

У Concurrent Rendering React може почати рендер, призупинити його, а потім продовжити, що призводило до того, що стилі вставлялися невчасно або навіть кілька разів, створюючи артефакти й мерехтіння контенту.

useInsertionEffect() вирішує це: він виконується під час фази «commit», до layout і до відмальовування, тому стилі гарантовано вставлені, перш ніж браузер щось намалює.


2. Порядок виконання хуків

Ось порядок, у якому React викликає ефекти:

ХукКоли виконуєтьсяОсновне призначення
useInsertionEffectДо layout і до paintВставка стилів / синхронні операції перед відмальовуванням
useLayoutEffectПісля DOM-коміту, але до paintВимірювання, позиціонування, синхронні зміни DOM
useEffectПісля paint (асинхронно)Побічні ефекти, підписки, логіка

Таким чином:

useInsertionEffect → useLayoutEffect → useEffect


3. Приклад (імітація роботи CSS-in-JS)

javascript
import { useInsertionEffect } from "react"; function DynamicStyle({ color }) { useInsertionEffect(() => { const style = document.createElement("style"); style.textContent = `.dynamic-text { color: ${color}; }`; document.head.appendChild(style); return () => { document.head.removeChild(style); }; }, [color]); return <p className="dynamic-text">Hello, world!</p>; }

Тут:

  • стиль вставляється в до того, як React намалює DOM;
  • користувач ніколи не бачить «нефарбований» текст;
  • при зміні кольору старі стилі видаляються.

4. Різниця з іншими ефектами

ХукЧас виконанняЧи може викликати reflow/paint?Використовувати для
useEffectПісля відмальовуванняможеПідписки, запити, side-effects
useLayoutEffectПісля DOM-коміту, до paintможе викликати reflowВимірювання, DOM-маніпуляції
useInsertionEffectДо layout, до paintніВставка стилів, бібліотечні ефекти

5. Особливості

Ви не повинні використовувати useInsertionEffect у звичайних застосунках. Цей хук призначений лише для бібліотек, які вставляють CSS синхронно.

React гарантує, що ефекти useInsertionEffect виконуються в порядку ієрархії дерева компонентів - це запобігає дублюванню або гонкам під час генерації класів.

Не можна читати layout або DOM усередині useInsertionEffect. Його завдання - вставка, а не вимірювання. Для вимірювань використовуй useLayoutEffect.


6. Приклад реального застосування (Emotion)

javascript
useInsertionEffect(() => { const sheet = document.head.querySelector('#emotion-styles'); sheet.insertRule(`.css-${hash} { color: ${color}; }`); }, [hash, color]);

Ця логіка дозволяє бібліотеці вставляти CSS «на льоту» до рендера браузера, без мерехтіння й артефактів під час переходів.


7. Підсумок

useInsertionEffect() - це низькорівневий, синхронний хук, який виконується ще до layout і paint, щоб бібліотеки могли вставити динамічні стилі в DOM вчасно, забезпечуючи стабільний зовнішній вигляд навіть за конкурентного рендерингу.


Коротко

ВластивістьЗначення
ВиконуєтьсяДо useLayoutEffect і useEffect
Сумісність із SSRТак
Для кого призначенийБібліотеки CSS-in-JS (Emotion, styled-components, JSS та ін.)
Чи можна читати DOM?Ні
Чи можна змінювати DOM (наприклад, вставити Так
Працює за concurrent renderingТак
Підтримується зReact 18+

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

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

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