javascript
yarn add lodash.debounce
const App = () => {
  const [searchValue, setSearchValue] = useState('');
  const searchHandler = useCallback(
    sdebounce((e) => {
      setSearchValue(e.target.value);
    }, 300),
    [],
  );
  return (
    <div>
      <div>{searchValue}</div>
      <input type="text" onChange={searchHandler} />
    </div>
  );
};
typescript
yarn add -D @types/lodash.debounce
useSearch.ts
import debounce from 'lodash.debounce';
import React, { useCallback, useState } from 'react';
export default function useSearch(callback?: (value: string) => void, wait = 300) {
  const [searchValue, setSearchValue] = useState('');
  const searchHandler = useCallback(
    debounce((e: React.ChangeEvent<HTMLInputElement>) => {
      const value = e.target.value;
      callback?.(value);
      setSearchValue(value);
    }, wait),
    [],
  );
  return { searchValue, searchHandler };
}