We use cookies for site analytics. Accept to help us understand how the site is used. See our Privacy Policy for details.
A medium frontend problem, graded against 4 test cases (2 of them hidden).
React and browser-platform problems - hooks, event handling, and rendering behaviour.
Reach for it when you see: A component, hook, or DOM-behaviour question rather than an algorithm.
More Frontendproblems →```tsx
export function SearchInput() {
const [query, setQuery] = useState("");
const [results, setResults] = useState<Result[]>([]);
const reqIdRef = useRef(0);
const abortRef = useRef<AbortController | null>(null);
// Debounce derived from query
useEffect(() => {
if (!query.trim()) { setResults([]); return; }
const handle = setTimeout(async () => {
// Cancel previous in-flight request
abortRef.current?.abort();
const ctl = new AbortController();
abortRef.current = ctl;
const myReqId = ++reqIdRef.current;
try {
const res = await fetch(`/api/search?q=${encodeURIComponent(query)}`, { signal: ctl.signal });
const data = await res.json();
// Race-condition guard: drop response if a newer request was issued
if (myReqId !== reqIdRef.current) return;
setResults(data);
} catch (e) {
if ((e as Error).name === "AbortError") return; // expected
// surface other errors
}
}, 300);
return () => clearTimeout(handle);
}, [query]);
return <input value={query} onChange={e => setQuery(e.target.value)} />;
}
```
Two protections, both needed:
1. Debounce (300ms typical) - waits for the user to pause typing before firing any request.
2. Cancellation / staleness check - guards against the race where requests for "rea", "rear", "react" are all in flight and the slow "rea" finishes last.
`AbortController` is the right tool: it actually stops the network request, saving bandwidth. The reqId guard is a belt-and-suspenders fallback for non-fetch requests or paths where abort isn't wired. Use both.
The full reference solution in every supported language stays in the editor above - reveal it there once you have had a real attempt.
These apply to the pattern as a whole, not just this problem.