useEffect vs useLayoutEffect
useEffect
and useLayoutEffect
are two hooks we can use to manage side effects. By side effect, we mean anything that should happen once the component is mounted or updated.
Both hooks consist of two functions (main effect function and optional cleanup function) and a dependency array which we use to tell react on what lifecycle of the component effect should run.
Dependencies array
[]
Empty array. Effect will run once when component mounts. Cleanup function runs when component unmounts.
[value, anotherValue]
Array with values. Effect will run once when component mounts. On every rerender React will check if any of the dependencies specified in the array changed. If any of them did, cleanup function runs with previous values, then main effect runs. Cleanup function runs last time when component unmounts.
null
No dependencies. Effect will run once when component mounts. On every rerender cleanup function runs with previous values, then main effect runs. Cleanup function runs last time when component unmounts.
React compares values in dependencies array via
Object.is
, which means shallow comparison. It will not work if you mutate arrays or objects.
Differences between useEffect
and useLayoutEffect
The following diagram explains the sequence of events for function components. While dependencies array regulates what is happening during component lifecycle, using a particular useEffect
hook lets us control when exactly during the lifecycle effect will take place.
Both effects happen after the DOM tree was built. So inside both effects, we can do operations with DOM elements.
However, useEffect
happens after the screen is rendered in the browser. The main consequence is that if we do something in our effect, that will affect the picture, user might see some twitching of changes happening. That means removing/adding elements, changing their position, color or other visual attributes. This won’t neccesserelly happen for you as a developer, since React is a pretty fast framework, and you are probably using a modern computer, which is not something all other users do.
Cons of useLayoutEffect
In short, it’s slower compared to useEffect
.
By using useLayoutEffect
we are saying to React that whatever the effect is going to do, it is absolutely essential that we wait for rendering the screen until it is done. And that is what React does for us, it blocks the browser from repainting.
That means double rendering, since, if you take a look at the diagram above, before any effect happens, DOM tree is built. So whatever our component’s JSX is, it’s already there. After that we calculate the layout effect which somehow changes the pictures (if it doesn’t, you don’t need useLayoutEffect
), and then React forces component to rerender immediately, building DOM the second time. During all those operations browser is blocked from painting.
Comments