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