Skip to message box
Kestrel
Ctrl K

Pinned

Today

Yesterday

Previous 7 days

Previous 30 days

Older

SSam RiveraKestrel Plus

Debounce a search input in React

How do I debounce a search input in React without a library? And when should I use debounce vs throttle?

Debouncing waits until the user stops typing before it runs the search, so you send one request instead of one per keystroke. Throttling runs at a steady pace while input keeps coming.

DebounceThrottle
FiresOnce, after input pausesAt most once per interval
Best forSearch, autosave, validationScroll, resize, drag
Typical delay250–400 ms100–200 ms

The hook

TSX
import { useEffect, useState } from "react";

export function useDebounce<T>(value: T, delay = 300) {
  const [debounced, setDebounced] = useState(value);

  useEffect(() => {
    const id = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(id); // reset on every keystroke
  }, [value, delay]);

  return debounced;
}

Debounce the query, not the input, so typing stays instant:

TSX
const [query, setQuery] = useState("");
const q = useDebounce(query, 300);

useEffect(() => {
  if (q) search(q);
}, [q]);
Tip: pair it with an AbortController so a slow, older request can never overwrite newer results.
  1. Keep the input controlled and instant; only the side effect waits.
  2. 300 ms is a good default; go lower for local filtering.
  3. The cleanup already cancels pending work on unmount.

Want the AbortController version, or a test using fake timers?

Kestrel Reason
Shift + Enter for a new line

Demo app: responses are simulated, not generated by a real model.