← All courses

useEffect & Component Lifecycle

🗓 May 31, 2026 ⏱ 2 min read

What is a side effect?

Rendering should be pure: given props and state, return UI. But apps also need to do things outside rendering — fetch data, start a timer, subscribe to events. These are side effects, and the useEffect hook is where they belong.

The shape of useEffect

import { useEffect, useState } from 'react';

function Clock() {
  const [time, setTime] = useState(new Date());

  useEffect(() => {
    const id = setInterval(() => setTime(new Date()), 1000);
    return () => clearInterval(id);   // cleanup when the component leaves
  }, []);                            // [] = run once, on mount

  return <Text>{time.toLocaleTimeString()}</Text>;
}

Three parts: the effect function (what to do), an optional cleanup function it returns (undo it), and the dependency array (when to run).

The dependency array controls timing

  • [] — run once, when the component first appears (mounts).
  • [userId] — run on mount and again whenever userId changes.
  • no array — run after every render (rarely what you want).

Fetching data with useEffect

function Profile({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    let active = true;
    fetch(`https://api.example.com/users/${userId}`)
      .then(res => res.json())
      .then(data => { if (active) setUser(data); });
    return () => { active = false; };   // avoid setting state after unmount
  }, [userId]);                          // refetch when userId changes

  if (!user) return <Text>Loading...</Text>;
  return <Text>{user.name}</Text>;
}

Why cleanup matters

If you start a timer, a subscription, or a network request, you must stop it when the component leaves — otherwise you leak resources or try to update a component that’s gone (a common warning). The returned cleanup function handles this.

The rules of hooks

  • Only call hooks at the top level of a component — never inside loops, conditions or nested functions.
  • Only call hooks from React components or custom hooks.

These rules let React reliably track each hook between renders.

Common mistakes

  • Forgetting the dependency array, causing an infinite fetch/render loop.
  • Missing a dependency the effect uses (stale data).
  • Not returning a cleanup for timers/subscriptions (leaks and warnings).
Summary: useEffect runs side effects like data fetching and timers. Control when it runs with the dependency array, and return a cleanup function to undo subscriptions/timers. Follow the rules of hooks.