3 ms·
Here's a quick review. I see two obvious issues: - you memoized the instantiation of Fuse (which is cheap), but `searcher.search()` (which is expensive) is per
by ht85 7y ago
Here's a quick review. I see two obvious issues:
- you memoized the instantiation of Fuse (which is cheap), but `searcher.search()` (which is expensive) is performed on every call, even if none of the parameters change.
- the imperative API (`search()` and `resetSearch()`) is not the idiomatic way to write hooks, as the component using the hook would have to call `useFuzzy()`, THEN call `search(currentInputValue)` on every render, which is awkward.
You could fix both by accepting a 3rd `keyword` argument and performing the search within the memoized function.
- thepratt 7y agoFor the 2nd point: would you suggest a useEffect hook that has a dependency on the search key? With the current search() call replaced with an update of the search key state.
- ht85 7y agoIt depends what you want. Your current code performs the search synchronously, in which case useEffect would not be useful. You would use useEffect if the search was done asynchronously, typically in a web worker. I would do it in a single useMemo hook like so: const defaultOptions = { tokenize: true, threshold: 0.2 }; export function useFuzzy<T>( data: T[], options: FuseOptions<T>, keyword: string, ): T[] { return useMemo(() => { if (!keyword) return data; const fuse = new Fuse<T>(data, { ...defaultOptions, ...options }); return fuse.search(keyword); }, [data, options, keyword]) } That way there is no duplication of the `keyword` variable, and it is now completely owned by the parent, making it much cleaner (especially if you're going to debounce it etc..). As debouncing would be standard if you're handling user typing, check out one of my favorite hooks: https://usehooks.com/useDebounce https://usehooks.com/useDebounce