React `useInsertionEffect`
`useInsertionEffect` is a specialized React hook for injecting or updating styles before layout effects run, primarily to support CSS-in-JS libraries. It operates at a very early point in React’s effect sequence and should rarely be used directly in application components.
`useInsertionEffect(setup, dependencies)` resembles `useEffect` and `useLayoutEffect`, but React runs it before layout effects. This timing lets a styling library insert rules into the document before code that measures or otherwise reacts to the rendered layout.
The hook is intended mainly for library authors implementing CSS-in-JS systems. A component normally should not use it merely because an effect needs to run early; ordinary synchronization belongs in `useEffect`, while DOM reads or synchronous DOM mutations that must happen before paint generally belong in `useLayoutEffect`.
Like other effect hooks, `useInsertionEffect` runs after React has committed the relevant DOM changes. Its setup function can return cleanup logic, and the dependency array controls when React re-runs the setup. Effects can be invoked more than once in development environments such as Strict Mode, so setup and cleanup should be safe to repeat.
There are important restrictions: code inside `useInsertionEffect` should not rely on refs being attached, and updates scheduled from it are not intended as a general state-management mechanism. Because it exists to solve a narrow styling-library timing problem, replacing it with `useEffect` or `useLayoutEffect` should be considered when the actual requirement is ordinary synchronization or DOM measurement.
Key points
- Runs before `useLayoutEffect`, making it suitable for style insertion timing.
- Primarily intended for CSS-in-JS and other library-level styling implementations.
- Do not use it as a general-purpose replacement for `useEffect` or `useLayoutEffect`.
- Refs are not intended to be relied on from an insertion effect.
- Setup and cleanup should tolerate repeated execution in development.
Interview questions
Why does React provide `useInsertionEffect` instead of having CSS-in-JS libraries use `useLayoutEffect`?
CSS-in-JS libraries may need their rules inserted before layout effects execute so that layout-related code observes the correct styling. `useInsertionEffect` provides a dedicated timing point before layout effects without forcing styling libraries to compete with application layout effects. This helps keep style injection from interfering with code that measures or reacts to the DOM. The hook is therefore a specialized primitive rather than a general application-effect API.
What is the difference between `useInsertionEffect`, `useLayoutEffect`, and `useEffect`?
All three are effect hooks, but they occupy different points in React's commit-time lifecycle. `useInsertionEffect` is intended primarily for inserting styles before layout effects, `useLayoutEffect` is useful for DOM measurement and synchronous layout-related work, and `useEffect` is the normal choice for synchronization that does not need to block painting. Choosing among them should be based on the required timing rather than on which hook appears to run fastest.
Can you use refs to access DOM nodes inside `useInsertionEffect`?
You should not rely on refs being attached when an insertion effect runs. The hook executes at an earlier point in the commit lifecycle specifically to support style insertion, so it does not provide the normal assumptions that make refs useful in layout effects. If code needs to inspect a DOM node through a ref, `useLayoutEffect` is generally the appropriate primitive. This distinction prevents styling-library timing requirements from being confused with DOM measurement requirements.
Would you use `useInsertionEffect` to fix a flickering UI in an application component?
Not automatically. First determine whether the flicker comes from CSS insertion, DOM measurement, or ordinary external synchronization. If the problem is dynamic CSS injection by a styling system, insertion effects may be appropriate at the library level; if the component must measure or synchronously adjust the DOM before paint, `useLayoutEffect` is more appropriate. For non-visual synchronization, `useEffect` is normally sufficient.
What cleanup considerations matter when implementing a style injector with `useInsertionEffect`?
The effect should clean up exactly the resources it created when its dependencies change or the component is removed. For a simple style element, that can mean removing the specific element that was inserted. More advanced CSS-in-JS systems often share style sheets or rules, so cleanup must account for reference counting or rule ownership rather than blindly removing an entire shared sheet. The implementation should also tolerate repeated setup and cleanup during development.