Start learning free

LESSON 86 OF 161 · FRONTEND: REACT EFFECTS AND DATA

Clean Up

Practice

A search box that asks the API on every key sends a request per letter. Typing "lam" would ask for "l", then "la", then "lam", and only the last answer matters. The fix is to wait: each key starts a 300 ms timer, and the request goes out only when the timer fires. If another key comes first, the old timer is cancelled.

Cancelling is the job of an effect's cleanup: the function the effect returns. React runs it before the effect runs again, and when the component leaves the page. Here is a cleanup on another job, a clock that ticks every second:

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

setTimeout gives back the timer's id, and clearTimeout(id) cancels that timer if it hasn't fired yet. With [search] as the effect's array, each key runs the cleanup of the key before it, so only the last timer is left to fire. An empty field has nothing to search for, so the effect stops right away. The text goes into the address after ?q=, so encodeURIComponent makes characters like & safe there.

The check types "la", lets 200 ms pass, types "m" and lets 300 ms pass. Your page must show:

> type "la" into "Search"
  field "Search": "la"
> 200 ms pass
  screen: no change
> type "m" into "Search"
  field "Search": "lam"
> 300 ms pass
  request: GET /api/products?q=lam -> 200
  list "Matches"
    item: Lamp $29

Without the cleanup, the same typing sends three requests: q=l, q=la and q=lam.

Your task: in src/App.jsx, below the products' effect, write an effect with [search] that waits 300 ms with setTimeout, then fetches /api/products?q= with the encoded text and stores the answer with setMatches. Its cleanup cancels the timer. The search state, the field and the Matches list are already there.


Assignment
Follow the Coding Tutorial to search as the visitor types, with a 300 ms timer and a cleanup that cancels it, so three quick keys make one request.


Hint
Keep the timer's id in a variable: const timer = setTimeout(…, 300);. The cleanup is the arrow function the effect returns, and it passes that id to clearTimeout.


STEP 1 OF 8
    Ctrl + Enter to check