What is the useEffect Hook in React?

Key takeaways:

  • The useEffect hook, introduced in React 16.8, allows functional components to handle side effects that were previously managed in class components.

  • The useEffect hook helps manage component lifecycles by mimicking methods like componentDidMount, componentDidUpdate, and componentWillUnmount.

  • useEffect can be used for tasks such as fetching data, manipulating the DOM, handling subscriptions, and performing cleanup operations.

  • The dependencies array in useEffect determines when the effect should re-run: it runs on every render without dependencies, only once on the initial render with an empty array, and when specific variables change when they are listed in the dependencies array.

  • Cleanup tasks can be performed by returning a function within the useEffect callback, which runs before the component unmounts or before the next effect execution.

  • The syntax for using useEffect is useEffect(callback, [dependencies]), where callback executes the effect and the dependencies array controls when it runs.

  • A practical use case for useEffect is in a chatbox component to load previous messages and indicate the user’s activity when the component first mounts.

Hooks were introduced in version 16.8 of React to enhance functional components, allowing them to manage state and other side effects traditionally handled in class components. One of these powerful Hooks is the useEffect hook in React functional components.

The React useEffect hook enables functional components to perform side effects at specific points in a component’s lifecycle:

  • When a component is first rendered (similar to componentDidMount function in class components)
  • When the component updates due to changes in specific values (similar to componentDidUpdate function in class components)
  • Just before the component is removed from the DOM (similar to componentWillUnmount function in class components)

With React useEffect, we can execute side-effect tasks like fetching data in React using fetch API, manipulating the DOM, or subscribing to events. We can also use multiple useEffect hooks within a component to separate different logic for better readability and maintainability.

Syntax

useEffect(callback, [dependencies]);

In the above syntax:

  • callback refers to the function that runs when the useEffect hook in React is triggered. This can be an arrow function.

  • dependencies is an optional array of variables that useEffect monitors. The hook re-runs only if any of the variables in this array change.

Controlling useEffect hook with dependencies

The dependencies array in React useEffect determines when useEffect hook should re-run. Here’s how different values for dependencies control the behavior:

Run useEffect on every render

If we want useEffect to execute on every render, simply omit the dependencies array:

useEffect(() => {
    // This code runs on every render
});

Run useEffect only once (on initial render)

To make React useEffect hook run only once when the component is initially mounted, pass an empty array [] as dependencies. This mimics the componentDidMount method in React class components:

useEffect(() => {
    // This code runs only on the initial render
}, []);

Run useEffect when certain values change

To trigger useEffect hook only when specific variables change, include them in the dependencies array. This is similar to componentDidUpdate method in React class components:

useEffect(() => {
    // This code runs only when  variable x changes
}, [x]);

Run cleanup code before component unmounts

To run a cleanup function before the component is removed from the DOM, return a function from within the callback function. This cleanup function in useEffect hook runs after the initial render and before every re-run of useEffect, ensuring that any previous side effects are cleared. This functionality is similar to componentWillUnmount method in React class components:

useEffect(() => {
    // Setup code

    return () => {
        // Cleanup code that runs before the component unmounts
    };
});

How to use useEffect in a chatbox component?

Consider a simple example of a chatbox component in React where we need to load previous messages using the useEffect hook and indicate that the user is active when the chatbox is first opened.

Code explanation

In the above ChatboxComponent.js file:

  • Lines 5–6: We use the useState hook to manage the state of the userActive and messages variables. You can explore the useState hook in more detail here.

  • Lines 8–29: The useEffect hook is employed here to perform an asynchronous operation—fetching data on mount—when the component is first rendered.

    • Lines 10–27: Since the callback function in useEffect hook cannot be directly asynchronous, we define an async function retrieveOldMessages within the callback and call it immediately. This approach allows us to handle asynchronous tasks like fetching data without issues.

    • Line 28: After the messages are fetched, we set the userActive status to true, indicating that the user is active in the chat.

    • Line 29: We pass an empty array [] as the dependencies parameter to ensure useEffect hook only runs once on the initial render, mimicking the componentDidMount method in class components.

Knowledge test

Let’s attempt a short quiz to assess your understanding.

Q

Which of the following statements about the useEffect hook in React is true?

A)

useEffect hook can only run on the initial render and cannot watch for changes in variables.

B)

useEffect hook cannot handle cleanup tasks when a component unmounts.

C)

useEffect hook allows functional components to handle side effects similar to lifecycle methods in class components.

D)

useEffect hook can only be used in class components, not in functional components.

Conclusion

The useEffect hook in React is a powerful tool, enabling React functional components to handle side effects, something previously possible only in class components. By controlling when useEffect runs through the dependencies array, we can effectively manage component lifecycles in React functional components, making our code more readable and easier to maintain. Whether we need to fetch data on component mount, watch for changes in specific variables, or clean up resources when a component unmounts, useEffect hook offers a flexible and powerful solution for handling side effects in React.

Understanding and mastering useEffect in React allows developers to build dynamic, efficient, and well-structured React applications. As you become more familiar with this hook, you’ll find it essential for managing side effects and enhancing the interactivity and responsiveness of the React components.

If you want to explore more about React, check out our blog, The best React developer roadmap for 2024, for in-depth insights into the latest React tools and best practices.

Frequently asked questions

Haven’t found what you were looking for? Contact Us


How to perform cleanup in useEffect hook in React?

To perform cleanup in useEffect hook, return a function from within the hook. This cleanup function runs before the component unmounts or before the next re-run of useEffect, ensuring any previous side effects are cleared. This is useful for unsubscribing or removing event listeners to prevent memory leaks.


What is the best way to fetch data in a React component with useEffect?

To fetch data with useEffect, define an asynchronous function within the hook and immediately call it. This approach allows you to handle asynchronous operations like API requests effectively, as the hook itself cannot be directly asynchronous.


When should we avoid using useEffect in React?

Avoid using useEffect when the logic can be handled directly within the render or if it’s not a side effect. For example, calculations, conditional rendering, or updating state based on props are best handled directly in the component or by other hooks like useMemo or useCallback.


Free Resources

Copyright ©2024 Educative, Inc. All rights reserved