Telerik blogs
ReactT2 Dark_1200x303

Although useEffect is enough for most of our needs, we should know about the useLayoutEffect hook—running synchronously, it can be used for things such as animations, measurements, mutations, etc.

Functional components have taken over the React community. The release of React Hooks made functional components much more powerful and reusable. Hooks allowed functional components to manage and declare state, reuse state logic and reduce code.

There are many different built-in hooks available in React and each one of them was created for a specific purpose.

We have the useState hook, made for declaration and management of the state. We have the useReducer hook that allows functional components in React access to reducer functions. And the useLayoutEffect is a powerful hook, but it doesn’t get as much attention as other hooks—perhaps for good reason.

We’re going to explore how the useLayoutEffect hook works and what the specific use cases are best for implementing this hook. But first, let’s look at some of the background.

Lifecycle Methods

Before the release of React Hooks, class components were essential for React applications. They were the standard for creating React components and lifecycle methods.

Every React component has different render cycle stages, such as mounting, updating and unmounting. For class components, we could use some functions that would be run in some specific render cycles of our component.

We have the componentDidMount lifecycle method that runs when the component is created and inserted into the DOM.

componentDidMount() {
  console.log("Rendered!");
}

We have the componentDidUpdate lifecycle method that runs after some update occurs in our component.

componentDidUpdate(prevProps) {
  if (this.props.user !== prevProps.user) {
    console.log("Updated");
  }
}

And we have the componentWillUnmount lifecycle method that runs when we want to remove our component from the DOM, also called unmounting.

componentWillUnmount() {
  console.log("Component unmounted!");
}

The useEffect Hook

The useEffect hook is a powerful combination of these lifecycle methods—replacing all of them with one single hook in our component. It makes our components more reusable, cleaner, more reliable and easier to test.

The useEffect hook allows React functional components to perform side effects. It receives a callback function and an array of dependencies as arguments.

useEffect(() => {
   // Here we can perform side-effects.
}, [dependencies]);

The useEffect hook can be used in different ways. We can call it every time our component renders, we can call it only once, or we can call it when only some value changes.

We can run the useEffect hook every time our component renders by simply passing our callback function. Using the useEffect hook without any array of dependencies as the second argument will cause it to run every time our component renders, so be careful of how you use it.

useEffect(() => {
  console.log('Run');
});

We can run the useEffect hook only once when our component mounts by simply passing an empty array of dependencies as a second argument.

useEffect(() => {
  console.log('Run only once');
}, []);

The array of dependencies is very important for the useEffect hook. We can pass any value that we want inside our array of dependencies and our useEffect hook will only run when any of these values changes.

Imagine that we have a value called username. We want our useEffect hook to run every time our username value changes. We can simply pass it to our array of dependencies inside our useEffect hook.

useEffect(() => {
  console.log("Run only when 'username' changes");
}, [username]);

The useEffect hook works asynchronously and we can have as many instances of it as we want inside our component.

Did you notice the highlighted word—asynchronously? Because this is the main difference between the useEffect and the useLayoutEffect hook.

The useLayoutEffect Hook

The useLayoutEffect hook works synchronously. It runs immediately after React has performed all DOM mutations. It will run after every render but before the screen is updated.

The useLayoutEffect hook is very useful for DOM updates. We can use it for DOM measurements (like a scroll position or styles for a specific element), animations, mutations, etc.

This is how the useLayoutEffect hooks work step-by-step:

  1. A re-render was caused inside a React component.
  2. React renders your component.
  3. useLayoutEffect runs synchronously.
  4. React waits for the useLayoutEffect to finish running.
  5. The screen is updated.

Let’s write some simple code using the useLayoutEffect hook to see how it works. We’re going to import the useState hook and pass an initial value to it.

import { useState, useLayoutEffect } from "react";

const App = () => {
  const [name, setName] = useState("Leonardo");

  return (
    <div>
      <h1>Hello {name}</h1>
    </div>
  );
};

We know that the useLayoutEffect runs after every render but before the screen is updated, right? So, we can update our name state value if we want to.

We’re going to use the useLayoutEffect hook for changing our name state value before the screen is updated. We’re going to make a comparison and check for a specific name (which is going to be our initial state value) and we’re going to change our name state to another name.

import { useState, useLayoutEffect } from "react";

const App = () => {
  const [name, setName] = useState("Leonardo");

  useLayoutEffect(() => {
    if (name === "Leonardo") {
      setName("Jose");
    }
  }, []);

  return (
    <div>
      <h1>Hello {name}</h1>
    </div>
  );
};

We can see that before our screen is updated, the name state is updated. The useLayoutEffect runs and updates the name state before the browser has a chance to paint.

Conclusion

Most of the time the useEffect hook is enough and it will serve us perfectly. It is the hook designed for running effects inside your React components.

The useLayoutEffect hook is very powerful and can help us to make important DOM measurements. We can use it for things such as animations, measurements, mutations, etc. Remember that the useLayoutEffect runs synchronously, which means that the application won’t be visually updated until your effect finishes running.

Many developers don’t know that the useLayoutEffect hook exists and have never used it before. The right decision is not to use the useLayoutEffect hook unless you really need it.


Leonardo Maldonado
About the Author

Leonardo Maldonado

Leonardo is a full-stack developer, working with everything React-related, and loves to write about React and GraphQL to help developers. He also created the 33 JavaScript Concepts.

Related Posts

Comments

Comments are disabled in preview mode.