Things you should know about useEffect & useLayoutEffect
A lot of posts talks about the difference between useEffect
and useLayoutEffect
. However, I couldn’t find anything related to have multiple useEffect
in a React component or even have useLayoutEffect
in it. Someone might argue that is a bad practice; in my opinion, it’s about exploring the possibilities. I share my findings in my post on using multiple useEffect
in single component. For those who wants to see code in action, here is the sandbox link.
In the following example, we have three useEffect
and one useLayoutEffect
. Do you know what the output of the console is?
The answer is:
If you didn’t get it answer right away, let me explain to you.
In first rendering phase, React checks if useLayoutEffect
exist, runs useLayoutEffect
before useEffect
. In our example, useLayoutEffect
has no dependency, it runs every time on every render. Next, our useState
initializes state variable theme
with value blue and counter
with value 0. Three useEffect
will run in order because their dependencies change. In the theme useEffect
, it updates a state counter
. React re-render because of state changes.
Now we are in the second render phase. First, React checks if useLayoutEffect
exist, runs useLayoutEffect
before useEffect
. In our example, useLayoutEffect
has no dependency, it runs again. Secondly, React checks if theme
has changed. No, skip the theme useEffect
. React checks if counter
has changed. Yes, from 0 to 1. Run the counter useEffect
. Next, run the useEffect
without dependency array.
My finding
useLayoutEffect
runs beforeuseEffect
.- Think
useEffect
with dependencies array asif
statement. If a value inside the dependencies array changes, run theuseEffect
. - The orders of useEffect matters. React calls
useEffect
after each render and the order is followed the order ofuseEffect
is being declared.
I encouraged you to clone the sandbox, rearranging the orders of useEffect
and add another useEffect
with on mount condition to have better understanding useEffect
and useLayoutEffect
. Cheers!
useEffect(()=> { console.log("mount.")}, []);