useInsertionEffect
Опасность
useInsertionEffect предназначен для авторов библиотек CSS-в-JS. Если вы не работаете над библиотекой CSS-в-JS и не нуждаетесь в месте для вставки стилей, вам, вероятно, нужен useEffect или useLayoutEffect.
useInsertionEffect позволяет вставлять элементы в DOM до запуска любых эффектов изменения макета.
useInsertionEffect(setup, dependencies?)
Справочник
useInsertionEffect(setup, dependencies?)
Вызовите useInsertionEffect для вставки стилей до запуска любых эффектов, которые могут потребовать чтения макета:
import { useInsertionEffect } from 'react';
// Inside your CSS-in-JS library
function useCSS(rule) {
useInsertionEffect(() => {
// ... inject <style> tags here ...
});
return rule;
} Параметры
-
setup: Функция с логикой вашего эффекта. Функция настройки также может необязательно возвращать функцию очистки. Когда ваш компонент добавлен в DOM, но до запуска любых эффектов изменения макета, React выполнит вашу функцию настройки. После каждого повторного рендеринга с изменёнными зависимостями React сначала выполнит функцию очистки (если вы её предоставили) со старыми значениями, а затем выполнит вашу функцию настройки с новыми значениями. Когда ваш компонент удалён из DOM, React выполнит вашу функцию очистки. -
необязательно
dependencies: Список всех реактивных значений, на которые ссылается кодsetup. К реактивным значениям относятся свойства, состояние и все переменные и функции, объявленные непосредственно внутри тела вашего компонента. Если ваш linter настроен для React, он проверит, что каждое реактивное значение правильно указано как зависимость. Список зависимостей должен иметь постоянное количество элементов и быть написан в строке, как[dep1, dep2, dep3]. React будет сравнивать каждую зависимость со своим предыдущим значением, используя алгоритм сравненияObject.is. Если вы не укажете зависимости, ваш эффект будет повторно выполняться после каждого повторного рендеринга компонента.
Возвращаемое значение
useInsertionEffect возвращает undefined.
Ограничения
- Эффекты выполняются только на клиенте. Они не выполняются во время серверного рендеринга.
- Вы не можете обновлять состояние внутри
useInsertionEffect. - К моменту выполнения
useInsertionEffectссылки ещё не прикреплены. -
useInsertionEffectможет выполняться как до, так и после обновления DOM. Не следует полагаться на обновление DOM в определённый момент. - В отличие от других типов эффектов, которые запускают очистку для каждого эффекта, а затем настройку для каждого эффекта,
useInsertionEffectзапустит как очистку, так и настройку по одному компоненту за раз. Это приводит к «переплетению» функций очистки и настройки.
Использование
Вставка динамических стилей из библиотек CSS-в-JS
Традиционно вы стилизовали компоненты React с помощью обычного CSS.
// In your JS file:
<button className="success" />
// In your CSS file:
.success { color: green; } Некоторые команды предпочитают создавать стили непосредственно в коде JavaScript вместо написания файлов CSS. Это обычно требует использования библиотеки CSS-в-JS или инструмента. Существует три распространённых подхода к CSS-в-JS:
- Статическая экстрация в файлы CSS с компилятором
- Встроенные стили, например
<div style={{ opacity: 1 }}> - Динамическая вставка тегов
<style>
Если вы используете CSS-в-JS, мы рекомендуем сочетание первых двух подходов (файлы CSS для статических стилей, встроенные стили для динамических стилей). Мы не рекомендуем динамическую вставку тегов <style> по двум причинам:
- Динамическая вставка заставляет браузер многократно пересчитывать стили.
- Динамическая вставка может быть очень медленной, если она происходит в неподходящее время в жизненном цикле React.
Первая проблема неразрешима, но useInsertionEffect помогает решить вторую проблему.
Вызовите useInsertionEffect для вставки стилей до запуска любых эффектов изменения макета:
// Inside your CSS-in-JS library
let isInserted = new Set();
function useCSS(rule) {
useInsertionEffect(() => {
// As explained earlier, we don't recommend runtime injection of <style> tags.
// But if you have to do it, then it's important to do in useInsertionEffect.
if (!isInserted.has(rule)) {
isInserted.add(rule);
document.head.appendChild(getStyleForRule(rule));
}
});
return rule;
}
function Button() {
const className = useCSS('...');
return <div className={className} />;
} Аналогично useEffect, useInsertionEffect не выполняется на сервере. Если вам нужно собрать используемые правила CSS на сервере, вы можете сделать это во время рендеринга:
let collectedRulesSet = new Set();
function useCSS(rule) {
if (typeof window === 'undefined') {
collectedRulesSet.add(rule);
}
useInsertionEffect(() => {
// ...
});
return rule;
} Узнайте больше о модернизации библиотек CSS-в-JS с динамической вставкой к useInsertionEffect.
Подробное описание
Почему это лучше, чем вставка стилей во время рендеринга или useLayoutEffect?
Если вы вставляете стили во время рендеринга, а React обрабатывает неоперативное обновление, браузер будет пересчитывать стили на каждом кадре во время рендеринга дерева компонентов, что может быть чрезвычайно медленным.
useInsertionEffect лучше, чем вставка стилей во время useLayoutEffect или useEffect, потому что это гарантирует, что к моменту выполнения других эффектов в ваших компонентах теги <style> уже были вставлены. В противном случае расчёты макета в обычных эффектах будут неверными из-за устаревших стилей.
© 2013–present Facebook Inc.
Licensed under the Creative Commons Attribution 4.0 International Public License.
https://react.dev/reference/react/useInsertionEffect