How to Fetch Data from an API with useEffect in React

One of the most important features of React is its ability that allows you to add side effects to function components such as fetching data, manipulating the DOM, and subscribing to events which allows you to perform side effects in your components.

We will take a closer look at how to use the useEffect hook in React. We will explain what the hook is, how it works, and provide examples of its use.

Syntax of useEffect:

import React, { useEffect } from 'react';

function ExampleComponent() {
  useEffect(() => {
    // do something when component mounts or updates
    return () => {
      // do something when component unmounts or updates
    };
  }, [/* dependency array */]);

  return (
    <div>Example Component</div>
  );
}

useEffect takes two arguments: a function that runs when the component mounts or updates, and a dependency array which specifies which variables the effect depends on. The effect function can return a cleanup function, which will run when the component unmounts or updates. The dependency array can be empty, in which case the effect runs only once when the component mounts.

Examples of common side effects

Fetching data from an API using useEffect:

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

function DataFetchingComponent() {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch('https://api.example.com/data');
        const json = await response.json();
        setData(json);
        setLoading(false);
      } catch (error) {
        setError(error);
        setLoading(false);
      }
    }
    fetchData();
  }, []);

  if (loading) {
    return <div>Loading...</div>;
  }

  if (error) {
    return <div>Error: {error.message}</div>;
  }

  return (
    <ul>
      {data.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}

This example uses useEffect to fetch data from an API when the component mounts. The useState hooks are used to hold the data, loading and error states while fetching the data. The data is then displayed on the screen.

Subscribing to a global event emitter using useEffect:

import React, { useEffect } from 'react';
import EventEmitter from './EventEmitter';

function EventListenerComponent() {
  useEffect(() => {
    const listener = (event) => {
      console.log('Event:', event);
    };
    EventEmitter.addListener('event', listener);
    return () => {
      EventEmitter.removeListener('event', listener);
    };
  }, []);

  return (
    <div>EventListener Component</div>
  );
}

This example uses useEffect to subscribe to a global event emitter when the component mounts. The cleanup function is used to unsubscribe when the component unmounts.

Modifying the DOM using useEffect:

import React, { useEffect } from 'react';

function ButtonComponent() {
  useEffect(() => {
    const button = document.getElementById('my-button');
    const handleClick = () => {
      console.log('Button clicked');
    };
    button.addEventListener('click', handleClick);
    return () => {
      button.removeEventListener('click', handleClick);
    };
  }, []);

  return (
    <button id="my-button">Click me</button>
  );
}

This example uses useEffect to add a click event listener to a button when the component mounts. The cleanup function is used to remove the event listener when the component unmounts.

Don't forget:

Declare all dependencies in the dependency array: It's important to declare all the dependencies of a useEffect function in the dependency array to ensure that the function is run at the right times. If a dependency is not included in the array, the effect function may not be

I hope after this article, you will have a better understanding of how to use the useEffect hook in your React components, be able to write more efficient and maintainable code, and have a deeper understanding of how React works.