Home / Blogs

What is UseEffect Hook & How to Manage Side Effects in React?

React JS
·

October 25, 2023

what-is-useeffect-hook-and-how-to-manage-side-effects-in-react

In React, managing side effects and handling component lifecycle events is an essential part of building dynamic and responsive applications. The UseEffect hook is a fundamental tool for achieving these goals in functional components.

In this comprehensive guide, we’ll dive deep into the UseEffect hook, exploring its purpose, syntax, and various use cases.

By the end of this blog, you’ll have a solid understanding of how to leverage UseEffect to manage side effects effectively in your React applications.

What is the UseEffect Hook?

The UseEffect hook is part of the React Hooks API, introduced in React 16.8. It allows you to perform side effects in your functional components. Side effects are actions that occur in a component other than rendering, such as data fetching, DOM manipulation, and setting up subscriptions.

Syntax of UseEffect

Before we delve into practical examples, let’s look at the syntax of the useEffect hook:

import React, { useEffect } from 'react';

function MyComponent() {

  useEffect(() => {
    // Side effect code goes here
  }, [dependency1, dependency2]);
  
}
  • The first argument is a function that contains the code for your side effect.
  • The second argument is an optional array of dependencies. If provided, the effect will only run when one or more of these dependencies change. If omitted, the effect runs after every render.

To read more about useState Hook in React & how to manage state in functional components, refer to our blog What is useState Hook in React & How to Manage State in Functional Components

Basic Usage: Fetching Data

One of the most common use cases for useEffect is data fetching. Let’s create a simple component that fetches and displays data from an API when it mounts.

import React, { useState, useEffect } from 'react';

function DataFetchingComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then((response) => response.json())
      .then((result) => setData(result))
      .catch((error) => console.error(error));
  }, []); // Empty dependency array, runs only once

  return (
    <div>
      {data ? (
        <ul>
          {data.map((item) => (
            <li key={item.id}>{item.name}</li>
          ))}
        </ul>
      ) : (
        <p>Loading...</p>
      )}
    </div>
  );
}

In this example, we use useState to manage the fetched data and useEffect to make the API request when the component mounts. Since we provide an empty dependency array, the effect runs once after the initial render.

Managing Cleanup with UseEffect

useEffect also allows us to clean up resources when a component unmounts or when dependencies change. This is important to prevent memory leaks. Let’s create a timer that starts when the component mounts and stops when it unmounts:

import React, { useState, useEffect } from 'react';

function TimerComponent() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const intervalId = setInterval(() => {
      setSeconds((prevSeconds) => prevSeconds + 1);
    }, 1000);

    // Cleanup function
    return () => {
      clearInterval(intervalId);
    };
  }, []); // Empty dependency array, runs only once

  return <div>Time: {seconds} seconds</div>;
}

Here, we use clearInterval in the cleanup function returned by UseEffect to stop the timer when the component unmounts. This ensures that we don’t have a lingering timer after the component is removed from the DOM.

Conditional Effects

Sometimes, you may want to conditionally run an effect based on a specific condition. For example, you might want to fetch data only when a certain prop changes. You can achieve this by including that prop in the dependency array:

import React, { useState, useEffect } from 'react';

function ConditionalDataFetching({ userId }) {
  const [data, setData] = useState(null);

  useEffect(() => {
    if (userId) {
      fetch(`https://api.example.com/user/${userId}`)
        .then((response) => response.json())
        .then((result) => setData(result))
        .catch((error) => console.error(error));
    }
  }, [userId]); // Include userId in the dependency array

  return (
    <div>
      {data ? (
        <p>User ID: {data.id}, Name: {data.name}</p>
      ) : (
        <p>Loading...</p>
      )}
    </div>
  );
}

In this example, the effect only runs when the userId prop changes. This prevents unnecessary API calls when other props or state variables change.

To read more about creating API Requests with React & Axios, refer to our blog How to Create API Requests With React & Axios in 2023

Conclusion

The UseEffect hook is a powerful tool for managing side effects and handling component lifecycle events in React functional components. Whether you’re fetching data, setting up timers, or performing cleanup, useEffect provides a clean and declarative way to manage side effects. Understanding its syntax and usage is essential for building dynamic and responsive React applications.

Horilla Editorial Team Author

Horilla Editorial Team is a group of experienced writers and editors who are passionate about HR software. We have a deep understanding of the HR landscape and are committed to providing our readers with the most up-to-date and informative content. We have written extensively on a variety of HR software topics, including applicant tracking systems, performance management software, and payroll software etc. We are always looking for new ways to share our knowledge with the HR community. If you have a question about HR software, please don't hesitate to contact us.