Core Concepts

Effects with useEffect

Learn how to perform side effects like data fetching, subscriptions, and DOM manipulation.

What is useEffect?

useEffect lets you synchronize a component with an external system — fetching data, setting up event listeners, updating the document title, etc.

The Dependency Array

  • No array: Effect runs after every render
  • Empty array `[]`: Effect runs only once (on mount)
  • With values `[a, b]`: Effect runs when a or b change

Cleanup Functions

Return a function from useEffect to clean up subscriptions, event listeners, or timers when the component unmounts or before the next effect runs.

Common Patterns

  • Fetching data on component mount
  • Subscribing to events
  • Setting up timers
  • Syncing with localStorage

Example

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

// Fetch data on mount
function UserList() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/users')
      .then(res => res.json())
      .then(data => {
        setUsers(data);
        setLoading(false);
      });
  }, []); // Empty array = run once on mount

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

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

// Effect with cleanup
function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds(prev => prev + 1);
    }, 1000);

    // Cleanup function
    return () => clearInterval(interval);
  }, []);

  return <p>Seconds elapsed: {seconds}</p>;
}

// Effect that responds to prop changes
function DocumentTitle({ title }) {
  useEffect(() => {
    document.title = title;
    return () => { document.title = 'My App'; };
  }, [title]); // Re-run when title changes

  return <h1>{title}</h1>;
}
Try it yourself — JSX