What is the useEffect Hook in React?

Key takeaways:

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

  • The useEffect Hook helps manage component life cycles 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 be 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 life cycle:

  • 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.

If you want to know more about hooks, please look into it: What are React hooks?

Syntax

useEffect(callback, [dependencies]);
Syntax of useEffect()

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 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 only once

Run useEffect when certain values change

To trigger the 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 useEffect when certain values change

Run cleanup code before the 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 the 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
};
});
Run cleanup code before 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.

Common mistakes while using useEffect

  1. Skipping the dependencies array:

    1. Omitting the dependencies array can cause the effect to run after every render, leading to performance issues.

  2. Mutating state inside effects without dependencies:

    1. This can cause an infinite loop of renders.

  3. Incorrect dependencies:

    1. Ensure all variables used in the effect are added to the dependencies array to avoid stale closures.

Best practices

  • Always include dependencies in the array.

  • Keep effects focused—one purpose per effect.

  • Use cleanup functions to avoid memory leaks.

Knowledge test

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

Q

Which statement about the useEffect Hook in React is true?

A)

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

B)

The useEffect Hook cannot handle cleanup tasks when a component unmounts.

C)

The useEffect Hook allows functional components to handle side effects similar to life cycle methods in class components.

D)

The 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 life cycles in React functional components, making our code more readable and easier to maintain. Whether we need to fetch data on the 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 the 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 ©2025 Educative, Inc. All rights reserved