A lot of developers are conversant with useEffect and how to use it but when asked about useLayoutEffect hooks and its use case, we become blank. I couldn’t spot the difference also as useLayoutEffect hooks are used in rare cases. I decided to check out the documentation to spot the difference.
This article is focused on explaining the two hooks, their differences and their use cases. The pre-requisite for this article is to be comfortable with basic React principles.
As developers, it is necessary we understand the technologies, tools, and languages we use to a large extent. This helps us apply the right principles to our project which in turn, would facilitate a better and more efficient application.
This article covers the following:
What is useEffect hook?
What is useLayoutEffect hook?
useEffect and useLayoutEffect - The Differences
useEffect and useLayoutEffect - Example
What is useEffect hook?
According to the React documentation, useEffect is a React Hook that lets you synchronize a component with an external system.
Syntax: useEffect (setup, dependencies?)
The setup in the above syntax represents the function with your effect’s logic. The setup function may also optionally return a clean-up function. When the components are first added or painted to the DOM, React will run the setup function and after every re-render with changed dependencies, React will first run the clean-up function (if provided) with the old values and then run the setup function again with the new values. After the component is removed from the DOM, React will run the clean-up function one last time.
Dependencies (optional): This has three forms; empty dependency array, no dependency provided and reactive value dependency provided. If no dependency is provided, React will run the useEffect function upon every DOM change. If an empty dependency array is provided, React will run the useEffect after only the first render i.e. this runs just once. If values are provided in the dependency, React with run useEffect if any of these values changes.
useEffect can be used in the following scenarios:
Connecting to an external system
Fetching data with effects
Controlling a non-react widget, etc.
Check out the official documentation for more detailed explanation.
A sample of useEffect Hook:
useEffect(() => {
// do something ...
return () => {
// clean up happens here
}
}, []) // dependencies are added here in the array
What is useLayoutEffect Hook?
useLayoutEffect is a version of useEffect that fires before the browser repaints the screen.
Syntax: useLayoutEffect (setup, dependencies?)
The setup in the above syntax represents the function with your effect’s logic. The setup function may also optionally return a clean-up function. Before the components are first added or painted to the DOM, React will run the setup function and after every re-render with changed dependencies, React will first run the clean-up function (if provided) with the old values and then run the setup function again with the new values. Before the component is removed from the DOM, React will run the clean-up function one last time.
Dependencies (optional): This is the same as the above – reference to useEffect Hook.
useEffect and useLayoutEffect - The Differences
One major difference between useEffect and useLayoutEffect is that useEffect runs after the browser has been painted i.e. the users must have seen the application before the code in useEffect runs while useLayoutEffect runs or blocks the browser from painting ensuring the code inside the useLayoutEffect runs before the browser displays or makes the application visible to the users.
useLayoutEffect affects the performance of the application as the browser is blocked until the computation is done by useLayoutEffect. useEffect does not block the browser.
It is advised to avoid this as much as possible except in rare cases where the application is dependent on a specific computation.
useEffect and useLayoutEffect - Example
Below is a simple useEffect and useLayoutEffect function that increments count
and num
by 1 respectively. The below code illustrates the difference. When the code below is compiled, the count
displays 0 and then changes to 1 within a second while num
displays 1 as soon as the code is rendered to the screen. We can observe a flick with the count
. This behaviour could confuse the users when this happens in a more complex application. To prevent the behaviour, useLayoutEffect becomes useful. When we need to compute some measurement before rendering our application, then we can use useLayoutEffect otherwise we can use the useEffect hook.
import { useEffect, useLayoutEffect, useState } from 'react'
const HooksUseCases = () => {
const [count, setCount] = useState(0)
const [num, setNum] = useState(0)
useEffect(() => {
console.log('excuting useEffect setup...')
setCount(c => c + 1)
return () => {
console.log('running useEffect cleanup here..')
setCount(0)
}
}, [])
useLayoutEffect(() => {
console.log('excuting useLayoutEffect setup...')
setNum(n => n + 1)
return () => {
console.log('running useLayoutEffect cleanup here..')
setNum(0)
}
}, [])
return (
<>
<p>useEffect Count {count}</p>
<p>useLayoutEffect Num {num}</p>
</>
)
}
export default HooksUseCases
In the above screenshots, we can see in the console that useLayoutEffect runs before useEffect. Here is a quick illustration of how the above code works when it is compiled:
count
andnum
renders with their initial value of 0 respectivelyReact places it in the DOM and runs the code in the useLayoutEffect
useLayoutEffect code updates the
num
value by 1 and triggers a re-render. The value ofcount
still remains 0 whilenum
has incremented by 1 giving it the value of 1React updates the DOM and the browser finally shows the update of
count
= 0,num
= 1After the browser has been painted, the useEffect code runs, incrementing
count
by 1 and trigger a re-render to update the DOM,count
= 1 andnum
= 1. We can observe a quick change ofcount
changing from 0 to 1 within milliseconds.React updates the DOM again and the browser finally shows the update of
count
= 1,num
= 1
Conclusion
In this article, we covered what useEffect and useLayoutEffect is and a sample of each hook. We also had a look at the difference and best use case for each of the hooks with a provided example to better understand the essence of this article.
It is recommended to look at the React documentation to better understand React hooks and how to use them. I would be writing more on these hooks. Now you should be able to differentiate between the two hooks and also identify when to apply each of the hook.
Thanks for reading.
Top comments (1)
I had an interview and they asked me this question so I only said both of those were used for the Mount life cycle and useLayoutEffect run before useEffect, I didn't know useLayoutEffect has better performance in specific situations
thank for sharing this great article