UseEffect Vs. UseLayoutEffect: Why UseEffect Is a better Choice?

Roman - Oct 2 - - Dev Community

Hey everyone! today we are going to take a deeper look at two mainly used reactjs life cycle hooks, named useEffect & useLayoutEffect. In this article, I’m trying to answer these questions, What are they? how do they work? what are their use cases? useEffect vs useLayout? Why useEffect is preferred over useLayoutEffect?

When building reactjs app, side effects are an essential part of our development process. Because, whenever we try to fetch data from an API, subscribe to an event, or update the DOM, managing side effects requires careful consideration of using the right hook. Before, react 18 only useEffect a life cycle hook was available, react version 18 added a new hook named useLayoutEffect hook. Both hooks perform side effects but have different workflow and purposes.

What is useEffect() and how it work?

useEffect hook is a life cycle hook for managing side effects. It runs after react has updated the DOM and the browser has painted the changes. In simple terms, useEffect allows us to execute code asynchronously after the UI has been rendered and visible to the user.

Take a look at an example given below:

import { useEffect } from "react";

function UserProfile({ userId }) {
  const [userData, setUserData] = useState(null);

  useEffect(() => {
    // Fetch user data when the component mounts
    fetch(`/api/user/${userId}`)
      .then(response => response.json())
      .then(data => setUserData(data));
  }, [userId]);

  return (
    <div>
      {userData ? <p>{userData.name}</p> : <p>Loading...</p>}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

In this example, inside the useEffect hook we make an API call. Making an API call does not block our UI, instead browser still paints our UI. In this case, because of the asynchronous nature, it skips the initial render and waits for the request to complete and update the UI in 2nd phase of the life cycle.

What is useLayoutEffect and how do they work?

Now, let’s talk about useLayoutEffect hook. This hook is similar to useEffect because it also performs the side effects, but this hook runs synchronously. This hook triggers right after react updates the DOM, but before the browser has a chance to paint the screen. That makes it useful for synchronous DOM measurements or manipulations where the layout is calculated before the screen is repainted. Learn more about Real DOM vs Virtual DOM in detail.

The key similarity in both hooks is that, they both trigger at the same spot and they both are used for the side-effect. The key difference is that:

  1. one Blocks the UI (run synchronously, useLayoutEffect)
  2. and the other does not block the UI (run asynchronously, useEffect)

Let’s take an example of useLayoutEffect hook:

import { useLayoutEffect, useRef } from "react";

function Tooltip({ content }) {
  const tooltipRef = useRef();

  useLayoutEffect(() => {
    const tooltip = tooltipRef.current;
    const { top, left } = tooltip.getBoundingClientRect();
    // Adjust the tooltip position based on its size
    tooltip.style.top = `${top}px`;
    tooltip.style.left = `${left}px`;
  }, []);

  return (
    <div ref={tooltipRef} className="tooltip">
      {content}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

In this example, using useLayoutEffect hook, we’re adjusting the position of a tooltip based on its size. This needs to happen before the browser repaints, so this hook ensures the adjustment is made in time.

Why useEffect is preferred over useLayoutEffect?

In React, both useEffect vs useLayoutEffect are hooks designed to manage side effects, but they function differently, which impacts performance and user experience.

  1. Because useEffect runs asynchronously, it’s a better choice for the vast majority of side effects in React. It allows the UI to be rendered without blocking, providing a smoother and faster user experience. This hook is preferred for tasks like fetching data, updating state, and setting up event listeners because it doesn’t interfere with the render cycle, making it more performance-friendly.
  2. Since useLayoutEffect is synchronous, it blocks the rendering process. If used inappropriately, it can lead to performance issues and make the UI sluggish, especially when dealing with heavy DOM operations. Every time React updates useLayoutEffect can delay the display of your UI.

That’s why, useEffect is preferred over the useLayoutEffect hook. Because it resolves performance issues, it is non-blocking and we can do much more then.

This post is originally posted at Programmingly.dev website. Here is the link to read full article: useEffect() vs useLayoutEffect(), why useEffect() is a better choice?

. . . . . . . . . . . . . . . . . . .