0
0
ReactHow-ToBeginner · 4 min read

How to Fetch Data in useEffect in React: Simple Guide

To fetch data in React, use the useEffect hook to run the fetch call after the component mounts. Inside useEffect, define an async function to fetch data and update state with useState, then call that function. This ensures data loads once and updates the component when ready.
📐

Syntax

The useEffect hook runs side effects like data fetching after the component renders. You usually define an async function inside it to fetch data, then update state with useState. The empty dependency array [] means it runs only once after the first render.

  • useEffect(() => { ... }, []): Runs once after mount.
  • Inside, define async fetch function.
  • Call fetch function to get data.
  • Update state to trigger re-render with new data.
javascript
import React, { useState, useEffect } from 'react';

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

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

  return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>;
}
💻

Example

This example fetches a list of users from a public API when the component loads. It shows "Loading..." while waiting, then displays the user names once data arrives.

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

export default function UserList() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchUsers() {
      const response = await fetch('https://jsonplaceholder.typicode.com/users');
      const data = await response.json();
      setUsers(data);
      setLoading(false);
    }
    fetchUsers();
  }, []);

  if (loading) return <p>Loading users...</p>;

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}
Output
<ul><li>Leanne Graham</li><li>Ervin Howell</li><li>Clementine Bauch</li><li>Patricia Lebsack</li><li>Chelsey Dietrich</li><li>Mrs. Dennis Schulist</li><li>Kurtis Weissnat</li><li>Nicholas Runolfsdottir V</li><li>Glenna Reichert</li><li>Clementina DuBuque</li></ul>
⚠️

Common Pitfalls

Common mistakes when fetching data in useEffect include:

  • Not using an async function inside useEffect (you cannot make the main function async).
  • Forgetting the empty dependency array [], causing infinite fetch loops.
  • Not handling loading or error states, which can confuse users.
  • Not cleaning up or cancelling fetches in some cases (advanced).
javascript
import React, { useState, useEffect } from 'react';

// Wrong: making useEffect callback async directly
function Wrong() {
  const [data, setData] = useState(null);

  useEffect(() => { // ❌ This is not allowed
    async function fetchData() {
      const response = await fetch('https://api.example.com/data');
      const json = await response.json();
      setData(json);
    }
    fetchData();
  }, []);

  return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>;
}

// Right: define async function inside useEffect
function Right() {
  const [data, setData] = useState(null);

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

  return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>;
}
📊

Quick Reference

  • useEffect(() => { ... }, []): Run once after mount.
  • Define async fetch function inside useEffect.
  • Call fetch function immediately.
  • Update state with useState to re-render.
  • Handle loading and error states for better UX.

Key Takeaways

Use an async function inside useEffect to fetch data after the component mounts.
Always include an empty dependency array [] to avoid repeated fetches.
Update state with useState to trigger re-render with fetched data.
Handle loading states to inform users while data loads.
Never make the useEffect callback function itself async.