Implement a React typeahead component that fetches suggestions as a user types and lets the user select one.
### Constraints & Assumptions
Use this explicit practice API: `loadSuggestions(query, signal)` returns a promise of `{id,label}` items with unique IDs; `onSelect(item)` receives a selection. Debounce nonempty queries by 250 ms. A newer query must never display an older response. Support loading, empty, error, mouse selection, and ArrowUp/ArrowDown/Enter/Escape interaction. The reported task does not specify these exact API or timing choices.
### Clarifying Questions
Should selecting a result replace the input? What happens on empty input? Can the loader abort requests? How should keyboard focus and active selection be represented?
### What a Strong Answer Covers
Controlled input, effect cleanup, stale-result protection, selection behavior, and combobox/listbox semantics.
### Follow-up Questions
Why is aborting a request alone insufficient? What happens if the component unmounts or the loader function changes? How would you test responses arriving in the opposite order from requests?
Overview: Implement a debounced React typeahead with stale-response protection, cancellation, loading/error states, keyboard selection, and accessible combobox semantics.
Implement a React typeahead component that fetches suggestions as a user types and lets the user select one.
Constraints & Assumptions
Use this explicit practice API: loadSuggestions(query, signal) returns a promise of {id,label} items with unique IDs; onSelect(item) receives a selection. Debounce nonempty queries by 250 ms. A newer query must never display an older response. Support loading, empty, error, mouse selection, and ArrowUp/ArrowDown/Enter/Escape interaction. The reported task does not specify these exact API or timing choices.
Clarifying Questions Guidance
Should selecting a result replace the input? What happens on empty input? Can the loader abort requests? How should keyboard focus and active selection be represented?
Why is aborting a request alone insufficient? What happens if the component unmounts or the loader function changes? How would you test responses arriving in the opposite order from requests?