React Fundamentals

Lesson 4 of 6

Effects and Side Effects

Rendering should stay pure, no fetching, no timers, no subscriptions. The useEffect hook is where that kind of side effect belongs.

import { useState, useEffect } from 'react';

function CourseList() {
  const [courses, setCourses] = useState([]);

  useEffect(() => {
    fetch('/api/courses')
      .then((res) => res.json())
      .then(setCourses);
  }, []); // empty array: run once, when the component mounts

  return (
    <ul>
      {courses.map((c) => <li key={c.id}>{c.title}</li>)}
    </ul>
  );
}

The dependency array

The second argument to useEffect controls when it re-runs:

Dependency arrayBehavior
omittedRuns after every render
[]Runs once, after the first render
[someValue]Runs once after the first render, then again whenever someValue changes

Cleaning up

If your effect subscribes to something (a timer, a WebSocket, an event listener), return a cleanup function from it, React calls it before the effect re-runs and when the component unmounts:

useEffect(() => {
  const id = setInterval(() => console.log('tick'), 1000);
  return () => clearInterval(id);
}, []);

📝 Effects Quiz

Passing score: 70%
  1. 1.What does an empty dependency array `[]` mean for useEffect?

  2. 2.To fetch data when a component first renders, you would use the ____ hook.

  3. 3.A function returned from inside useEffect is used to clean up before the next run or on unmount.