useFuseSearch.ts 867 B

123456789101112131415161718192021222324252627
  1. import {useCallback, useMemo} from 'react';
  2. import Fuse from 'fuse.js';
  3. type FuseSearchParams<T> = Parameters<Fuse<T>['search']>;
  4. export function useFuseSearch<T extends Record<string, unknown>>(
  5. data: T[],
  6. options: Fuse.IFuseOptions<T>
  7. ) {
  8. const searchIndex = useMemo(() => {
  9. return new Fuse(data, options);
  10. // purposely ignoring options as it will cause the effect to infinitely run
  11. // data is sufficient as the index should only change if data ever changed
  12. // eslint-disable-next-line react-hooks/exhaustive-deps
  13. }, [data]);
  14. const search = useCallback(
  15. (pattern: FuseSearchParams<T>[0] | undefined, opts?: FuseSearchParams<T>[1]) => {
  16. if (!pattern) {
  17. return data;
  18. }
  19. return searchIndex.search(pattern, opts).map(result => result.item);
  20. },
  21. [searchIndex, data]
  22. );
  23. return {search, searchIndex};
  24. }