Problem
useSearch creates the Sifter instance once and never refreshes it when the caller receives a new items prop. Select and InputSelect both memoize searchItems from props.items, but the search index can continue scoring against the original item list.
This is especially visible when items are loaded asynchronously, replaced after filtering, or refreshed from remote data.
Impact
Users can see stale, missing, or mismatched autocomplete suggestions after the items prop changes. Because search result IDs are mapped back into the latest items array by index, stale index data can also point at the wrong item.
Code references
src/hooks/useSearch.ts#L5: new Sifter(items) is stored in a ref only on initial render.
src/hooks/useSearch.ts#L8-L11: warm-up effect runs only once.
src/hooks/useSearch.ts#L21-L23: result IDs are mapped into the current items array.
src/components/Select/Select.tsx#L53-L70: Select passes memoized searchItems into useSearch.
src/components/InputSelect/InputSelect.tsx#L37-L55: InputSelect does the same.
Acceptance criteria
- Search index updates whenever the effective
items array changes.
- Searching after an
items prop replacement returns results from the new data only.
- Empty search after an
items prop replacement returns the new item list.
- Regression tests cover
items changing after initial render for both Select or the shared hook behavior.
Problem
useSearchcreates theSifterinstance once and never refreshes it when the caller receives a newitemsprop.SelectandInputSelectboth memoizesearchItemsfromprops.items, but the search index can continue scoring against the original item list.This is especially visible when items are loaded asynchronously, replaced after filtering, or refreshed from remote data.
Impact
Users can see stale, missing, or mismatched autocomplete suggestions after the
itemsprop changes. Because search result IDs are mapped back into the latestitemsarray by index, stale index data can also point at the wrong item.Code references
src/hooks/useSearch.ts#L5:new Sifter(items)is stored in a ref only on initial render.src/hooks/useSearch.ts#L8-L11: warm-up effect runs only once.src/hooks/useSearch.ts#L21-L23: result IDs are mapped into the currentitemsarray.src/components/Select/Select.tsx#L53-L70:Selectpasses memoizedsearchItemsintouseSearch.src/components/InputSelect/InputSelect.tsx#L37-L55:InputSelectdoes the same.Acceptance criteria
itemsarray changes.itemsprop replacement returns results from the new data only.itemsprop replacement returns the new item list.itemschanging after initial render for bothSelector the shared hook behavior.