Exercise 2: Why the Debounce Cleanup Function Matters — Possible Solution ==================================================================== WHAT HAPPENS WITHOUT THE CLEANUP FUNCTION ------------------------------ useEffect re-runs the entire effect function every time query changes - meaning a new setTimeout gets scheduled on every keystroke. Without return () => clearTimeout(timeoutId), none of those earlier timers ever get cancelled - each one is still sitting there, waiting to fire. Typing five characters quickly would eventually fire five separate search requests once each timer's delay elapses, not just one - the debounce delay would only push the flood of requests later in time, it wouldn't actually prevent it. WHY THE FIX IS "THE SAME LESSON" AS CHAPTER 4 ------------------------------ In both cases, useEffect starts something (a camera stream in Chapter 4, a pending timer here) that keeps existing independently of the component's own render cycle, and in both cases that same effect function runs again on every relevant change (the onDetected callback changing in Chapter 4, query changing here). The underlying discipline is identical: whatever the previous run of an effect started must be explicitly cleaned up before or as the next run begins, or that earlier thing keeps running in the background unintentionally - a stray camera stream draining battery in one case, a stray pending timer flooding the server with requests in the other. WHY THIS WORKS AS AN ANSWER ------------------------------ It correctly explains that omitting cleanup lets every keystroke's timer eventually fire regardless of later keystrokes, still resulting in excess requests despite the delay, and correctly identifies the shared underlying principle with Chapter 4 - cleaning up whatever the previous effect run started before the next run begins.