useInsertionEffect
useInsertionEffect
es una versión de useEffect
que se dispara antes de cualquier mutación del DOM.
useInsertionEffect(setup, dependencies?)
Referencia
useInsertionEffect(setup, dependencies?)
Llama a useInsertionEffect
para insertar los estilos antes de cualquier mutación en el DOM:
import { useInsertionEffect } from 'react';
// En tu librerÃa CSS-in-JS
function useCSS(rule) {
useInsertionEffect(() => {
// ... inyecta las etiquetas <style> aquà ...
});
return rule;
}
Ver más ejemplos a continuación.
Parámetros
-
setup
: La función con la lógica de tu Effect. Tu función setup puede opcionalmente devolver una función de limpieza. Antes de que tu componente sea añadido primero al DOM, React ejecutará tu función setup. Después de cada re-renderizado con dependencias modificadas, React ejecutará primero la función de limpieza (si es que la habÃas incluido) con los valores antiguos y entonces ejecutará tu función setup con los nuevos valores. Antes de que tu componente sea eliminado del DOM, React ejecutará tu función de limpieza una última vez. -
opcional
dependencias
: La lista de todos los valores reactivos referenciados dentro del el código desetup
. Los valores reactivos incluyen props, estado y todas las variables y funciones declaradas directamente dentro del cuerpo de tu componente. Si tu linter está configurado para React, verificará que cada valor reactivo esté correctamente especificado como dependencia. La lista de dependencias tienen que tener un número constante de elementos y que sean escritos en lÃnea como[dep1, dep2, dep3]
. React comparará cada dependencia con su valor previo usando el algoritmo de comparaciónObject.is
. Si no especificas ninguna dependencia, tu Effect se re-ejecutará después de cada re-renderizado del componente.
Retorno
useInsertionEffect
devuelve undefined
.
Advertencias
- Effect que sólo se ejecuta en el cliente. No se ejecutan durante el renderizado en el servidor.
- No puedes actualizar el estado dentro de
useInsertionEffect
. - En el tiempo en que
useInsertionEffect
se ejecuta, las referencias aún no han sido acopladas y el DOM todavÃa no ha sido actualizado.
Uso
Inyectando estilos dinámicos desde librerÃas CSS-in-JS
Tradicionalmente, añadirÃas estilo a los componentes de React usando CSS plano.
// En tu archivo JS:
<button className="success" />
// En tu archivo CSS:
.success { color: green; }
Algunos equipos prefieren incluir sus estilos directamente en el código JavaScript en lugar de escribir archivos CSS. Esto normalmente requiere usar una librerÃa CSS-in-JS o una herramienta. Existen tres formas comunes de plantear el CSS-in-JS que puedes encontrar:
- Extracción estática de archivos CSS con un compilador
- Estilos en lÃnea, ej.
<div style={{ opacity: 1 }}>
- Inyección durante el runtime de las etiquetas
<style>
Si usas CSS-in-JS, recomendamos la combinación de los dos primeros enfoques (archivos CSS para estilos estáticos, estilos en lÃnea para estilos dinámicos). No recomendamos la inyección durante el runtime de la etiqueta <style>
por dos razones:
- La inyección durante el runtime fuerza al navegador a recalcular los estilos mucho más a menudo.
- La inyección durante el runtime puede ser muy lenta si ocurre en un tiempo inadecuado en el ciclo de vida de React.
El primer problema no es solucionable pero useInsertionEffect
te ayuda a resolver el segundo problema.
Llama a useInsertionEffect
para insertar los estilos antes de cualquier mutación del DOM:
// En tu librerÃa CSS-in-JS
let isInserted = new Set();
function useCSS(rule) {
useInsertionEffect(() => {
// Como hemos explicado antes, no recomendamos la inyección durante el runtime de las etiquetas <style>.
// Pero si tienes que hacerlo, entonces es importante que sea dentro del useInsertionEffect.
if (!isInserted.has(rule)) {
isInserted.add(rule);
document.head.appendChild(getStyleForRule(rule));
}
});
return rule;
}
function Button() {
const className = useCSS('...');
return <div className={className} />;
}
De forma similar a useEffect
, useInsertionEffect
no se ejecuta en el servidor. Si tienes que agrupar las reglas CSS has usado en el servidor, puedes hacerlo durante el renderizado:
let collectedRulesSet = new Set();
function useCSS(rule) {
if (typeof window === 'undefined') {
collectedRulesSet.add(rule);
}
useInsertionEffect(() => {
// ...
});
return rule;
}
Lee más sobre actualizar librerÃas CSS-in-JS con la inyección en runtime useInsertionEffect
.
Deep Dive
Si insertas los estilos durante el renderizado y React está procesando una actualización no bloqueante, el navegador recalculará los estilos en cada frame mientras renderiza un árbol de componentes, lo que puede ser extremadamente lento.
useInsertionEffect
es mejor que insertar estilos durante useLayoutEffect
o useEffect
porque asegura que en el tiempo en que otros Efectos se ejecuten en tus componentes, las etiquetas <style>
ya han sido añadidas. De otro modo, los cálculos de layout en Effects regulares podrÃan ser incorrectos por los estilos desactualizados.