The type of the data objects.
The keys of D that are searchable (string or number fields).
The array of data objects to search through.
The keys within each object to match the search string against.
Optionalwait: number = 300Debounce delay in milliseconds before applying the search input.
Optionalfilters: ((item: D) => boolean)[]Optional array of custom filter functions to further refine results.
Object containing:
setUserInput: Debounced setter for the search input string.searchResult: Resulting list after applying search and filters.clearSearch: Clears the current search input and cancels debounce.searchString: Current raw (unprocessed) input value used for search.const {
setUserInput,
searchResult,
clearSearch,
searchString
} = useSearch(users, ['name', 'email'], 300, [user => user.active]);
<input onChange={e => setUserInput(e.target.value)} value={searchString} />
<button onClick={clearSearch}>Clear</button>
{searchResult.map(user => <div key={user.id}>{user.name}</div>)}
export const useSearch = <
D extends ObjectType,
K extends keyof D = StringNumberKeys<D>,
>(
data: D[],
searchKeys: K[],
wait: number = 300,
filters?: ((item: D) => boolean)[]
): {
setUserInput: (value: string) => void;
searchResult: D[];
clearSearch: () => void;
searchString: string;
} => {
const [searchString, setSearchString] = useState<string>('')
const { callback: setUserInput, cancel: cancelDebounce } = useDebouncedCallback(setSearchString, wait)
const condition = useMemo(() => (item: D) => {
return filters && filters.length
? filters.every(filter => filter(item))
: true
}, [filters]
)
const searchResult = useMemo(() => {
if (!searchString.length && (!filters || !filters.length)) return data
const lowerCasedSearch = searchString.toLowerCase()
return data.filter(v =>
condition(v) && searchKeys.some(searchKey => {
const value = v[searchKey]
return typeof value === 'string' || typeof value === 'number'
? `${value}`.toLowerCase().includes(lowerCasedSearch)
: false
})
)
}, [searchString, data, searchKeys, condition])
const clearSearch = useCallback(() => {
cancelDebounce()
setSearchString('')
}, [])
return {
setUserInput,
searchResult,
clearSearch,
searchString,
}
}
Custom React hook for performing debounced search and optional filtering over an array of objects.
This hook allows for efficient search operations with built-in debounce and additional filter support. It supports searching across multiple string or number keys of the data objects.