useEffect Is Not a Lifecycle Hook: The Synchronization Model

Hands-on practice for this lecture. Work through the exercises and quizzes to reinforce what you've learned.

1

Exercise 1 of 3

Dependency Array Quiz

Three useEffect snippets, three questions. Test how well you can predict when an effect runs based on its dependency array.

1
useEffect(() => {
  document.title = 'Hello';
});

How often does this effect run?

2
useEffect(() => {
  fetchUser(userId);
}, []);

When does this effect run? (userId is a prop)

3
useEffect(() => {
  const id = setInterval(() => {
    setCount(c => c + 1);
  }, 1000);
  return () => clearInterval(id);
}, []);

The cleanup function runs…

0/3 answered

2

Exercise 2 of 3

Spot the Infinite Loop

Four useEffect snippets. Identify which ones cause infinite re-render loops and understand the pattern behind each one.

For each snippet, decide: does this cause an infinite loop?

1

Snippet 1

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

useEffect(() => {
  setCount(count + 1);
}, [count]);
2

Snippet 2

const [data, setData] = useState(null);

useEffect(() => {
  fetch('/api/user')
    .then(r => r.json())
    .then(setData);
}, []);
3

Snippet 3

const [user, setUser] = useState({});

useEffect(() => {
  setUser({ name: 'Durgesh' });
}, [user]);
4

Snippet 4

const [theme, setTheme] = useState('dark');

useEffect(() => {
  document.body.className = theme;
}, [theme]);

0/4 answered

💡 Pattern: if your effect modifies a value that is in its own dep array, check whether the modification can cause a new render cycle. Object/array literals in deps always create new references.

3

Exercise 3 of 3

Add the Cleanup

Live editor: a custom hook leaks a resize listener because it has no cleanup. Add the return function to fix the memory leak.

Task

The useWindowWidth hook attaches a resize listener but never removes it. Every time the component mounts, a new listener piles up — a classic memory leak. Add the cleanup function so the listener is removed when the component unmounts.

Loading editor…

💡 Hint: useEffect can return a function. React calls it before the next effect run and on unmount. That is where you remove listeners, cancel timers, and abort fetches.

Practice: useEffect Is Not a Lifecycle Hook: The Synchronization Model — Interactive Exercises | Durgesh Rai