CodingNic

Build Movie Discovery

Connect Search with a Debounced Query

Build Movie Discovery 11 min read

Connect Search with a Debounced Query

Connect Search with a Debounced Query

Make the search box responsive while preventing a request on every keystroke. The local input value should change immediately; the URL should change only after the user pauses briefly.

Step 1 — Track the input value locally

Add local state initialized from the server-supplied query prop.

typescript
const [searchValue, setSearchValue] = useState(query);

Keep it synchronized when browser navigation or another control changes the query.

typescript
useEffect(() => {
  setSearchValue(query);
}, [query]);

Step 2 — Hold the debounce timer

Add a ref to remember the active timeout.

typescript
const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

Step 3 — Create the search handler

When the user types, update the local state immediately. Clear any previous timer, then schedule pushParams for 400 milliseconds later.

typescript
function onSearchChange(value: string) {
  setSearchValue(value);
  if (debounceRef.current) clearTimeout(debounceRef.current);
  debounceRef.current = setTimeout(() => pushParams({ q: value }), 400);
}

Step 4 — Connect the input

Replace the read-only behavior with the local value and the handler.

typescript
value={searchValue}
onChange={(e) => onSearchChange(e.target.value)}

Checkpoint

Type a title quickly. The input should respond to every keystroke, but the URL and movie results should update after the short pause rather than on every key press.