useEffect
useEffect lets you run side effects after rendering — things like fetching data, setting up subscriptions, updating the document title, or integrating with non-React libraries.
React components should be pure functions (no side effects during render). useEffect is React's dedicated place for code that needs to interact with the outside world.
Fetching data on component mount, listening to events, syncing with localStorage, setting up timers, updating page title. The dependency array controls WHEN it runs.
useEffect(callback, [dependencies]). Empty [] = run once on mount. [id] = run when id changes. No array = run after every render (usually wrong).
Code Examples
#1useEffect patterns
"use client";import { useState, useEffect } from "react";// Pattern 1: Fetch data on mountfunction UserList() {const [users, setUsers] = useState([]);const [loading, setLoading] = useState(true);const [error, setError] = useState(null);// [] = run once when component appears (mounts)useEffect(() => {async function fetchUsers() {try {const res = await fetch("https://jsonplaceholder.typicode.com/users");const data = await res.json();setUsers(data);} catch (err) {setError(err.message);} finally {setLoading(false);}}fetchUsers();}, []); // empty array = run onceif (loading) return <p>Loading...</p>;if (error) return <p>Error: {error}</p>;return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>;}// Pattern 2: Re-fetch when a dependency changesfunction UserProfile({ userId }: { userId: number }) {const [user, setUser] = useState(null);useEffect(() => {fetch(`https://jsonplaceholder.typicode.com/users/${userId}`).then(r => r.json()).then(setUser);}, [userId]); // re-runs whenever userId changesreturn <div>{user?.name}</div>;}// Pattern 3: Cleanup (event listeners, subscriptions)function WindowWidth() {const [width, setWidth] = useState(window.innerWidth);useEffect(() => {const handleResize = () => setWidth(window.innerWidth);window.addEventListener("resize", handleResize);// Cleanup function — runs when component unmountsreturn () => {window.removeEventListener("resize", handleResize);};}, []); // only set up oncereturn <p>Window width: {width}px</p>;}
Practice This Concept
Open the playground, paste any example, and experiment. The best way to learn is by breaking things.
Open in Playground