CPCODELAB
React

Fetching Data with useEffect

11 min read

Loading Remote Data

The classic pattern for data fetching combines useEffect (to trigger the request) with useState for the data, loading, and error states.

jsx
function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    let cancelled = false;
    setLoading(true);

    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(data => {
        if (!cancelled) {
          setUser(data);
          setLoading(false);
        }
      })
      .catch(err => {
        if (!cancelled) {
          setError(err.message);
          setLoading(false);
        }
      });

    return () => { cancelled = true; };
  }, [userId]);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error}</p>;
  return <h2>{user?.name}</h2>;
}

In production apps, prefer a data-fetching library like SWR or TanStack Query over raw useEffect. They handle caching, deduplication, revalidation, and loading states for you.

Ready to test yourself?
Practice React— quiz & coding exercises