Many developers know React, but a lack of understanding can lead to assumptions about how things work. Having a clear understanding of the hooks flow in React can greatly improve your code quality. After working with React for over 4 years, I'd like to share some key insights about the flow of React hooks, a concept that is often overlooked.
Before diving into hooks flow, I would like to revisit the rules of hooks
1. Only call Hooks at the top level
Don’t call Hooks inside loops, conditions, or nested
functions.Instead, always use Hooks at the top level of your
React function, before any early returns
2. Only call Hooks from React functions(Component or Custom Hook)
Don’t call Hooks from regular JavaScript functions.
React Hooks Flow
This React hooks flow diagram helps visualize the order in which hooks are called during different phases of a component's lifecycle.
Let's explore each phase of the component lifecycle.
Initial Mount
This is when a component loads on the screen for the first time.
Run lazy initializers
In React, state initialization occurs only once throughout a component's lifecycle.
By 'initializing,' I mean the initial value of useState
will be assigned to the variable only once.
this is quite normal and usually not a concern. However, it becomes more important when initialization involves complex computations, such as setting state from local storage.
const [userList, setUserList] = useState(localStorage.getItem("usersList"))
currently, localStorage.getItem("usersList") is executed on every re-render, but its result isn't assigned to the state variable. This repeated evaluation can lead to performance issues. To avoid this, you can pass a callback function to useState
, which will only be executed once, during the mounting phase.
const [userList, setUserList] = useState(() => localStorage.getItem("usersList"))
This is called lazy initialization of state, read more here
Lazy initialization helps prevent unnecessary initialization logic from running on every re-render.
Note: Only use the initializer function if there is a computation involved in state initialization.
Render
In this step React calls the function(component) to generate the virtual DOM representation of that component. This process does not directly mean that the component is visible to the user on the screen. Instead, it involves React creating a virtual DOM object that describes what the UI should look like.
Here's an example of a virtual DOM (VDOM) object:
const ComponentA = () => {
return <h1>Hello World!</h1>
}
VDOM object
{
$$typeof: Symbol(react.element),
key: null,
props: {children: 'Hello World!'},
ref: null,
type: "h1" ,
.....
};
React updates DOM
After generating the virtual DOM and reconciling it to get the final virtual DOM, React updates the actual DOM accordingly.
Run LayoutEffects
This step involves running the useLayoutEffect
hook, which is similar to useEffect
but executes before the browser performs any painting, see more here
Browser paints screen
Browser paints the DOM onto the screen
Run Effects
This is the step where the useEffect
hook runs, i.e after rendering the UI on the browser
If there is a state update in a useEffect
, it trigger the update lifecycle of the component
Update
When any state update is triggered, it triggers update lifecycle of the component
Render, React updates DOM
These steps are similar to the mounting phase
Cleanup LayoutEffects
After creating the virtual DOM (VDOM) and updating the actual DOM, React runs the cleanup functions for useLayoutEffect
hooks.
Note: If the dependencies of a
useLayoutEffect
haven’t changed, its cleanup function will not run.
Run LayoutEffects
If any dependency comparison returns false, indicating a change, the useLayoutEffect
will run again; otherwise, it will not.
Browser paints screen
At this point, the browser renders the updated DOM onto the screen.
Cleanup Effects, Run Effects
useEffect
cleanup and execution happen only if there is a change in dependencies compared to the previous render. If no dependencies have changed, neither the cleanup function nor the effect will run.
Unmount
This is the final phase of a component's lifecycle, where the component is removed from the DOM and is no longer visible to the user.
Cleanup LayoutEffects, Cleanup Effects
Before removing a component from the DOM, React runs all cleanup functions for both useLayoutEffect
and useEffect
hooks.
Next time you encounter a bug in the UI, visualize the hooks flow to pinpoint the right spot in your code to investigate and resolve the issue. I hope this helps you improve your coding skills. Happy coding!
Top comments (0)