injection for two reasons: **

  1. Runtime injection forces the browser to recalculate the styles a lot more often. 
  2. Runtime injection can be very slow if it happens at the wrong time in the React lifecycle. 

The first problem is not solvable, but ` useInsertionEffect ` helps you solve
the second problem.

Call ` useInsertionEffect ` to insert the styles before any layout Effects
fire:

    
    
    // 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} />;  
    
    
    }

Similarly to ` useEffect ` , ` useInsertionEffect ` does not run on the
server. If you need to collect which CSS rules have been used on the server,
you can do it during rendering:

    
    
    let collectedRulesSet = new Set();  
    
    
      
    
    
    function useCSS(rule) {  
    
    
      if (typeof window === 'undefined') {  
    
    
        collectedRulesSet.add(rule);  
    
    
      }  
    
    
      useInsertionEffect(() => {  
    
    
        // ...  
    
    
      });  
    
    
      return rule;  
    
    
    }

[ Read more about upgrading CSS-in-JS libraries with runtime injection to `
useInsertionEffect ` . ](https://github.com/reactwg/react-18/discussions/110)

#####  Deep Dive

####  How is this better than injecting styles during rendering or
useLayoutEffect?

Show Details

If you insert styles during rendering and React is processing a [ non-blocking
update, ](/reference/react/useTransition#marking-a-state-update-as-a-non-
blocking-transition) the browser will recalculate the styles every single
frame while rendering a component tree, which can be **extremely slow.**

` useInsertionEffect ` is better than inserting styles during [ `
useLayoutEffect ` ](/reference/react/useLayoutEffect) or [ ` useEffect `
](/reference/react/useEffect) because it ensures that by the time other
Effects run in your components, the ` <style> ` tags have already been
inserted. Otherwise, layout calculations in regular Effects would be wrong due
to outdated styles.

[ Previous  useImperativeHandle  ](/reference/react/useImperativeHandle) [
Next  useLayoutEffect  ](/reference/react/useLayoutEffect)

* * *

How do you like these docs?

[ Take our survey!  ](https://www.surveymonkey.co.uk/r/PYRPF3X)

* * *

[ ](https://opensource.fb.com/)

©  2024

[ Learn React ](/learn)

[ Quick Start ](/learn)

[ Installation ](/learn/installation)

[ Describing the UI ](/learn/describing-the-ui)

[ Adding Interactivity ](/learn/adding-interactivity)

[ Managing State ](/learn/managing-state)

[ Escape Hatches ](/learn/escape-hatches)

[ API Reference ](/reference/react)

[ React APIs ](/reference/react)

[ React DOM APIs ](/reference/react-dom)

[ Community ](/community)

[ Code of Conduct
](https://github.com/facebook/react/blob/main/CODE_OF_CONDUCT.md)

[ Meet the Team ](/community/team)

[ Docs Contributors ](/community/docs-contributors)

[ Acknowledgements ](/community/acknowledgements)

More

[ Blog ](/blog)

[ React Native ](https://reactnative.dev/)

[ Privacy ](https://opensource.facebook.com/legal/privacy)

[ Terms ](https://opensource.fb.com/legal/terms/)

[ ](https://www.facebook.com/react) [ ](https://twitter.com/reactjs) [
](https://github.com/facebook/react)

##  On this page

  * Overview 
  * Reference 
  * ` useInsertionE