← 전체 글로 돌아가기

Next.js

Fixing Stale Results in a React Debounced Search

A short React tutorial for preventing earlier search responses from replacing newer ones.

Debounce did not guarantee response order

Typing quickly into a search box sometimes showed results for a query I had already erased. A debounce reduced requests, but a request that had already started could still finish after a newer one.

Cancel both the timer and the request

AbortController gave the effect a clear cleanup path.

useEffect(() => {
  const controller = new AbortController();
  const timer = setTimeout(async () => {
    try {
      const res = await fetch(`/api/search?q=${encodeURIComponent(query)}`, {
        signal: controller.signal,
      });
      setResults((await res.json()).items);
    } catch (error) {
      if ((error as Error).name !== "AbortError") setError("Search failed");
    }
  }, 300);
  return () => { clearTimeout(timer); controller.abort(); };
}, [query]);

I also clear results before fetching when the query is empty. Without that branch, old results stay below an empty field.

Test under bad network conditions

Try rapid typing, deletion, and a Slow 3G network profile. Also navigate away while a request is pending. Debounce controls frequency; cancellation controls which response is allowed to update the screen.