We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies.

We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies. Less

We use cookies and other tracking technologies... More

Login or register
to publish this job!

Login or register
to save this job!

Login or register
to save interesting jobs!

Login or register
to get access to all your job applications!

Login or register to start contributing with an article!

Login or register
to see more jobs from this company!

Login or register
to boost this post!

Show some love to the author of this blog by giving their post some rocket fuel 🚀.

Login or register to search for your ideal job!

Login or register to start working on this issue!

Login or register
to save articles!

Login to see the application

Engineers who find a new job through JavaScript Works average a 15% increase in salary 🚀

You will be redirected back to this page right after signin

Blog hero image

What is useLayoutEffect Hook & how it compares to useEffect?

Abhinav Anshul 13 December, 2021 | 5 min read

React Hooks were released a couple of years ago when React ecosystem introduced a new way to handle state and effects in a function-based component. Although there isn't any sudden plan to completely deprecate the class-based approach, however, web applications have been moving to hooks rapidly. In this article, we'll look into the useLayoutEffect hook and its similarities & differences with the useEffect hook.

A side-effect hook

Before we dive into useLayoutEffect, it is worth mentioning that both this and the useEffect hook is used to handle side-effects in React.


Another way of saying this would be when the DOM paints the screen, we want to do some activity called side-effects that could include data fetching, updating and changing DOM elements, subscribing to an event etc.


What is useLayoutEffect?


According to the official docs,

"The signature is identical to useEffect, but it fires synchronously after all DOM mutations."



As it has two parts, let's look at the first statement, "signature is identical to useEffect",


useEffect and useLayoutEffect shares similar function signatures, meaning the API exposed to the developers are similar in both cases.


Given below is a simple counter application using useEffect that increments the count on a button click and prints the value using effect hook in the console.





function App(){

 const [count, setCount] = React.useState('0')

  React.useEffect(() => {

    console.log(count)

  }, [count])

  

return(

 <div>

  <h1>The count is {count} </h1>

  <button onClick={() => setCount(count + 1)}></button

 </div>

 )

}


If we replace useEffect hook with this instead,



React.useLayoutEffect(() => {

  console.log(count)

}, [count])

  

The Counter app would still work the same, this establishes the fact about having identical function signatures as,



useLayoutEffect(() => {

 // run effect here

}, [<dependency array>])

One thing to note here, it also returns either a cleanup function or an undefined value similar to the useEffect hook.



Moving onto the next statement, "but it fires synchronously after all DOM mutations.", this is where useLayoutEffect differentiates itself from useEffect hook, by the order in which they are fired.



In the above useEffect counter example, here's how React is rendering the function and handling interactivity:


a. When the App component gets mounted to the screen, the default count value 0 is printed along with the HTML button.



The count is 0.


b. The user clicks on the button and increments the count value by 1.

c. React triggers the state value of the count mentioned in the useState hook, and re-renders the count value.

d. After the DOM is done with painting the screen with mutated value, useEffect hook is triggered.


In a nutshell, a useEffect hook only gets triggered once DOM is done painting the screen, making it asynchronous as it doesn't block the DOM manipulation on the screen.


However, things gets a little more interesting with useLayoutEffect. It gets triggered synchronously. In other words, it doesn't care if the DOM has painted the screen.


We'll deep dive into its working below:


1. Execution Order


As we have seen, useLayoutEffect doesn't wait for DOM to paint the screen and gets fired right away. This sure affects the order of execution.


In a useEffect hook,


useEffect(() => {

  console.log("log 1")

}, [])

  

useEffect(() => {

  console.log("log 2")

}, [])


The code prints:


log 1

log 2


This is an expected behaviour while working with useEffect. It executes in the order in which they were mentioned.


Now, let's replace the second hook with a useLayoutEffect :



useEffect(() => {

  console.log("log 1")

}, [])

  

useLayoutEffect(() => {

  console.log("log 2")

}, [])

  


The above prints,


log 2

log 1


As expected, the useLayoutEffect doesn't care for DOM mutation hence gets executed even before the useEffect hook.


Join our newsletter
Join over 111,000 others and get access to exclusive content, job opportunities and more!

2. Performance

The official React doc suggests using the useEffect hook as much as possible and there is a 99% per cent chance it will suit most of the use cases in any application.


As useLayoutEffect is synchronous, React waits for it to finish then updates the screen.


As of rule of thumb, you can think of it as an App component that would wait to get visually updated until the useLayoutEffect has been finished running.


This pauses the React component for a split second, as it is "waiting" for something to be finished, this behaviour might cause a performance hiccup.


Hence performance-wise, useLayoutEffect can be expensive to run.


3. Visual Incosistencies

In complex user interaction which involves animations, it is possibly better to use useLayoutEffect instead of useEffect especially if you're dealing with ref



React.useLayoutEffect(() => {

  console.log(ref.current)

})


In the above, contrived example, useLayoutEffect ensures to wait, updates its value then move on to the other piece of code. This might improve on the animation flickering which usually happens with the useEffect hook.

This is a tradeoff between running expensive hook v/s having a smooth animation. However, React is fast enough to optimize on small use cases and we won't be bothered between the two at all.



4. useLayoutEffect & SSR

There's an infamous useLayoutEffect warning,


"Warning: useLayoutEffect does nothing on the server because its effect cannot be encoded into the server renderer's output format..."


When dealing with SSR, both useEffect & useLayoutEffect won't work unless that JavaScript has been properly loaded. Therefore, there's the above warning we might see in the console. The reason why it doesn't generate with useEffect is, it is not concerned with the render cycle of the component unlike useLayoutEffect is concerned and cares what users would see on the very first render of the component.

React Community suggests two ways to fix this,

1. Of course, the first thing we can do is to try to convert it to a useEffect hook if possible.

2. If there is a flickering issue with the useEffect (as we discussed earlier ) and developers do need useLayoutEffect, then another way could be delaying that very component that uses the hook until the JavaScript has been loaded. Another way of saying, lazily load the React Component.




Wrapping Up


In this post, we read how similar useEffect & useLayoutEffect can appear to be. However, the order in which both these hooks gets called is completely different. In small scale applications, both might look interchangeable but the latter shines while dealing with complex user animations, handling refs in React, dealing with Layout on a page etc. Although useLayoutEffect can be a little expensive to deal with compared to the useEffect hook, there are always tradeoffs while building applications. Finally, we learnt about how to use it with an SSR based application.



Some Important Resources that I have collected over time:

  1. https://reactjs.org/docs/hooks-reference.html#uselayouteffect
  2. https://kentcdodds.com/blog/useeffect-vs-uselayouteffect
  3. https://blog.bhanuteja.dev/the-lifecycle-of-react-hooks-component
  4. https://stackoverflow.com/questions/66148855/is-uselayouteffect-preferable-to-useeffect-when-reading-layout
  5. https://gist.github.com/gaearon/e7d97cdf38a2907924ea12e4ebdf3c85

Loved this post? Have a suggestion or just want to say hi? Reach out to me on Twitter

Author's avatar
Abhinav Anshul
(づ ◕‿◕ )づ

Related Issues

open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 4
  • Intermediate
  • HTML
open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 4
  • Intermediate
  • HTML
open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 5
  • Intermediate
  • HTML
open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 1
  • Intermediate
  • HTML

Get hired!

Sign up now and apply for roles at companies that interest you.

Engineers who find a new job through JavaScript Works average a 15% increase in salary.

Start with GitHubStart with Stack OverflowStart with Email