Start learning free

LESSON 87 OF 161 · FRONTEND: REACT EFFECTS AND DATA

Ignore the Old Answer in JavaScript

Practice

When a page sends several requests, the answers don't have to come back in the same order. The search box asks for "l", "la" and "lam". If the answer for "l" arrives last and goes into setMatches, the list shows the matches for "l" while the field says "lam". That old answer is stale: the page should drop it.

The fix lives in the effect. Each run makes its own flag, let ignore = false. The run's cleanup, which React calls as soon as the dependency changes, sets it to true. Just before storing the answer, the run checks its flag, and if it's true the answer is dropped. Here is the same idea on another route, a product loaded by its id:

useEffect(() => {
  let ignore = false;
  async function loadProduct() {
    const response = await fetch("/api/products/" + id);
    const data = await response.json();
    if (!ignore) setProduct(data);
  }
  loadProduct();
  return () => {
    ignore = true;
  };
}, [id]);

The flag is a plain let inside the effect, not a state: every run gets its own, and only that run's cleanup and answer can reach it. (Another way you'll meet: an AbortController, whose cleanup cancels the request itself.) The timer's clearTimeout stays too: it stops quick keys from sending requests at all, and ignore guards the requests already on their way.

The check makes the API answer later requests first, types "lam" and lets 300 ms pass. Today all three keys ask, and the list ends up showing Lamp, Plant and Stapler: the answer for "l". Your page must show:

> from now on, later requests are answered first
> type "lam" into "Search"
  field "Search": "lam"
> 300 ms pass
  request: GET /api/products?q=lam -> 200
  list "Matches"
    item: Lamp $29

Your task: in the search effect of src/App.jsx, add a flag ignore for each run, set it to true in the cleanup, stop before setMatches when it's true, and cancel the timer in the cleanup again.


Assignment
Follow the Coding Tutorial to drop the answers of old searches, so the Matches list always belongs to the text in the field.


Hint
The check goes after both await lines and before setMatches: the cleanup can run during either wait. In the cleanup, set the flag first, then call clearTimeout(timer).


STEP 1 OF 4
    Ctrl + Enter to check

    Effect Stale Answer in JavaScript

    Keep going with JavaScript1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free