import {useCallback, useMemo} from 'react'; import Fuse from 'fuse.js'; type FuseSearchParams = Parameters['search']>; export function useFuseSearch>( data: T[], options: Fuse.IFuseOptions ) { const searchIndex = useMemo(() => { return new Fuse(data, options); // purposely ignoring options as it will cause the effect to infinitely run // data is sufficient as the index should only change if data ever changed // eslint-disable-next-line react-hooks/exhaustive-deps }, [data]); const search = useCallback( (pattern: FuseSearchParams[0] | undefined, opts?: FuseSearchParams[1]) => { if (!pattern) { return data; } return searchIndex.search(pattern, opts).map(result => result.item); }, [searchIndex, data] ); return {search, searchIndex}; }