# Unexpected uses of useLayoutEffect

The docs describe [useLayoutEffect](https://reactjs.org/docs/hooks-reference.html#uselayouteffect) as a DOM targeted escape hatch for visual updates to the UI. Why then is a hook like this showing up in:
- Compatibility shims for [`useSyncExternalStore`](https://github.com/facebook/react/blob/main/packages/use-sync-external-store/src/useSyncExternalStoreShimClient.js)
- Reference implementation for the proposed [`useEvent`](https://github.com/reactjs/rfcs/blob/useevent/text/0000-useevent.md#internal-implementation) hook addition?
- In the react-redux [useSelector](https://github.com/reduxjs/react-redux/blob/9306158197afcb03ad4e2b56e53fa5115320f354/src/hooks/useSelector.js) implementation (before being moved over to useSyncExternalStore).

My answer is that there seems to be an emergent use case of `useLayoutEffect`, one that takes advantage of when it happens to run the React update process. I'd describe it as a lifecycle hook for other hooks. To understand why, let's look at the original use case for `useLayoutEffect`.

## Original Superpower: Run Before Browser Paint

Here is the ordering for when React updates the DOM and when effects run.
![When useEffect runs.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1655750339663/dkpbLgRXq.png align="left")

React explicitly yields the main thread to let the browser paint the frame. This is a departure from the old component lifecycle `componentDidMount` but it is in most cases what you want and more performant for synchronization effects that don't immediately have visual updates.

When you do have visual updates, however, doing them in the `useEffect` can cause flicker in the UI. `useLayoutEffect` offers an escape hatch for this:

![When useLayoutEffect runs.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1655750776401/gpYMXPBYP.png align="left")

This is the original use case and animation libraries like [Framer Motion](https://www.framer.com) make use of it for performant animations.

## New Superpower: Run before useEffect

There is another important property of `useLayoutEffect`, however: It runs before `useEffect`:

![When only hooks run.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1655751067238/IJd5VZTdX.png align="left")

Why is this important? It's for the use case of setting up non-rendering infrastructure across components. Effects and event handlers need to operate on the latest references, for example, but updating them in the render body is impure and `useEffect` may be too late. Although hooks have explicit execution order within a component, there is no guarantee in React that a particular component will update before any other.

I did not write any of these examples but here is my stab at why `useLayoutEffect` was used in:
- Old `useSelector` implementation: Essentially 'initializes' the selector by updating references for event handlers/effects, creating the subscription and evaluating it again on the update.
- `useEvent` compatibility shim: The updates references that the stable `useEvent` points to before the possibility of event handlers or effects using stale references. It is [pointed out that this is not a complete solution](https://twitter.com/dan_abramov/status/1521942665188847618), though, because other `useLayoutEffect` calls could still reference stale references
- `useSyncExternalStore`: [The code comment](https://twitter.com/dan_abramov/status/1521942665188847618) above the `useLayoutEffect` usage explicitly mentions it needs to saving something for a check that happens in `useEffect`. 

I believe this usage of `useLayoutEffect` is indicative of the need for a new injection point in the React update process, which is being addressed via things like `useSyncExternalStore` and `useEvent`. I believe such usage will fade away as React develops appropriate abstractions but it's interesting to think back on how emergent practices in the community get turned into new features.



