my-swiss-knife: - v1.9.9
    Preparing search index...

    Function useSearch

    • 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.

      Type Parameters

      • D extends ObjectType

        The type of the data objects.

      • K extends string | number | symbol = StringNumberKeys<D>

        The keys of D that are searchable (string or number fields).

      Parameters

      • data: D[]

        The array of data objects to search through.

      • searchKeys: K[]

        The keys within each object to match the search string against.

      • Optionalwait: number = 300

        Debounce delay in milliseconds before applying the search input.

      • Optionalfilters: ((item: D) => boolean)[]

        Optional array of custom filter functions to further refine results.

      Returns {
          clearSearch: () => void;
          searchResult: D[];
          searchString: string;
          setUserInput: (value: string) => void;
      }

      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,
      }
      }