useEffect Hook

🪝 Introduction to useEffect

The useEffect Hook is a React Hook that lets you perform side effects in functional components. A side effect is any operation that interacts with something outside of React's rendering process, such as fetching data, updating the document title, setting up timers, or subscribing to events.

Important

useEffect runs after React renders the component. It is designed for synchronizing your component with external systems.

🎯 Why Use useEffect?

React components should focus on rendering the user interface. Whenever you need to perform work after rendering, useEffect provides a clean and predictable way to do it.

  • Fetch data from APIs.
  • Update the browser's document title.
  • Start or stop timers.
  • Subscribe to external events.
  • Synchronize with third-party libraries.

⚙️ Syntax

Basic Syntax

useEffect(() => {
  // Side effect

  return () => {
    // Cleanup (optional)
  };
}, [dependencies]);
PartDescription
Effect FunctionRuns after the component renders.
Cleanup FunctionRuns before the effect executes again or before the component unmounts.
Dependency ArrayControls when the effect should run.

🔄 How useEffect Works

Component Renders
React Updates the UI
useEffect Executes
Dependencies Change?
Component Unmounts → Cleanup Executes
Yes → Cleanup Runs (if provided)
Effect Executes Again

💻 Example 1: Running an Effect Once

Component Mount

import { useEffect } from "react";

function Welcome() {
  useEffect(() => {
    console.log("Component mounted");
  }, []);

  return <h1>Welcome!</h1>;
}

The empty dependency array [] tells React to run the effect only once after the component's initial render.

📄 Example 2: Updating the Document Title

Document Title

import { useEffect, useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `Count: ${count}`;
  }, [count]);

  return (
    <button onClick={() => setCount(count + 1)}>
      {count}
    </button>
  );
}

Whenever count changes, React updates the document title after rendering the component.

⏰ Example 3: Using a Timer

Timer Example

import { useEffect, useState } from "react";

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

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

    return () => clearInterval(id);
  }, []);

  return <h2>{seconds}</h2>;
}

The cleanup function removes the timer when the component is unmounted, preventing memory leaks.

🌐 Example 4: Fetching Data

Fetching Data

import { useEffect, useState } from "react";

function Users() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    async function loadUsers() {
      const response = await fetch("/api/users");
      const data = await response.json();
      setUsers(data);
    }

    loadUsers();
  }, []);

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

The effect runs after the first render, fetches data from the server, and updates the component state.

📊 Dependency Array Behavior

Without a dependency array, the effect runs after every render.

An empty dependency array [] causes the effect to run only once after the initial render.

When dependencies are specified, the effect runs after the initial render and again whenever one of those dependency values changes.

🧹 Cleanup Functions

A cleanup function is returned from the effect. React executes it before running the effect again and before the component is removed from the page.

Cleanup Function

useEffect(() => {
  window.addEventListener("resize", handleResize);

  return () => {
    window.removeEventListener("resize", handleResize);
  };
}, []);

Tip

Always clean up event listeners, timers, subscriptions, and other external resources to avoid memory leaks.

📋 Common Use Cases

Use CaseExample
API RequestsFetch products or user data.
Browser APIsUpdate the document title.
TimersCreate intervals and timeouts.
SubscriptionsListen for WebSocket or event updates.
Third-party LibrariesInitialize charts or maps.

⚠️ Common Mistakes

  • Forgetting to include required dependencies.
  • Ignoring cleanup for timers or event listeners.
  • Using useEffect for calculations that belong in rendering.
  • Triggering unnecessary effects by including unstable values in the dependency array.

✅ Best Practices

  • Use useEffect only for side effects.
  • Always provide accurate dependencies.
  • Keep each effect focused on one responsibility.
  • Return cleanup functions when working with external resources.
  • Split unrelated side effects into separate useEffect calls.

📚 Official Resource

Learn more about useEffect in the official React documentation at React useEffect Documentation.

Summary

The useEffect Hook enables React components to perform work after rendering, such as fetching data, updating browser APIs, managing timers, and interacting with external systems. By understanding dependencies and cleanup functions, you can build efficient, predictable, and maintainable React applications.