effects

useInsertionEffect

Runs before any DOM mutations from the current render are applied, giving CSS-in-JS libraries a chance to inject <style> tags first. Reach for it only if you are authoring a styling library — application code should not use it.

useInsertionEffect(setup, dependencies?)

Parameters & Behavior

Parameter Purpose
setup Side effect that runs before layout effects can read the DOM
dependencies Same rules as useEffect — re-runs when deps change
no ref access You cannot read refs here — they aren't populated yet
no state updates Scheduling updates here is not allowed at this stage of commit

Examples

useInsertionEffect(() => {
  const style = document.createElement('style');
  style.textContent = rule;
  document.head.appendChild(style);
  return () => style.remove();
}, [rule]);

Inject a dynamic style rule before any layout effect measures the DOM

useInsertionEffect(() => {
  cache.insert(className, cssText);
}, [className, cssText]);

Emotion/styled-components style caches use this pattern internally

// Library code only — application components should call useLayoutEffect or useEffect instead.

Guidance: reserve for style-injection primitives

useInsertionEffect(() => { registerTheme(themeVars); return () => unregisterTheme(themeVars); }, [themeVars]);

Register CSS custom properties for a theme before layout runs

Gotcha

Refs are not yet attached and you cannot schedule updates — this is a narrow hook meant for style injection. Introduced in React 18; misuse produces subtle timing bugs.

Related hooks

← All React hooks · Fix hydration mismatch