Problem Statement
When building lookup fields, autocomplete searchbars, or filter menus, triggering network requests on every keypress causes substantial database overhead, wastes user bandwidth, and can trigger API rate-limiting.
Your task is to build a reusable, debounced search component in React. The component must wait for a brief period of inactivity (e.g. 300ms) before executing a search request.
Additionally, because network requests resolve asynchronously and can complete in a different order than they were sent, you must handle network race conditions to ensure that old requests don't overwrite newer, correct results.
Requirements
Functional
- Debounced Input: Capture user typing, but delay updating the debounced search term until typing pauses for a designated interval (e.g., 300ms).
- Mock API Integration: Trigger a simulated network search function when the debounced term updates.
- Loading & Empty States:
- Show a loading indicator/spinner while a network request is pending.
- Show a clear "No results found" message if the request succeeds but returns no matching items.
- Race Condition Prevention: Ignore the response of a pending search request if a new keystroke initiates a subsequent search query.
- Cleanup on Unmount: Properly clear any active timeouts or pending promises if the component unmounts.
Non-Functional
- The code must handle custom delays (e.g., allow passing a custom
delayin ms). - Maintain clean UI states using Tailwind CSS classes.
- Ensure accessibility by providing proper attributes (e.g.
role="search", loading status announcements).
Concepts Tested
- Custom hooks creation (
useDebounce). - Cleaning up side-effects in
useEffectreturn functions. - Managing async states (loading, success, error, empty).
- Resolving race conditions using abort signals or boolean cleanup locks.
