Web Totals

useDebounce

const useTimeout = (callback, delay) => {
  const refCallback = useRef();
  const refTimeout = useRef();

  useEffect(() => {
    refCallback.current = callback;
  }, [callback]);

  const set = useCallback(() => {
    refTimeout.current = setTimeout(() => refCallback.current(), delay);
  }, [delay]);

  const clear = useCallback(() => {
    refTimeout.current && clearTimeout(refTimeout.current);
  }, []);

  useEffect(() => {
    set();
    return clear;
  }, [delay, set, clear]);

  const reset = useCallback(() => {
    clear();
    set();
  }, [set, clear]);

  return { clear, reset };
};

const useDebounce = (callback, delay, dependencies) => {
  const { reset, clear } = useTimeout(callback, delay);
  useEffect(reset, [...dependencies, reset]);
  useEffect(clear, []);
};

const App = () => {
  const [count, setCount] = useState(10);
  useDebounce(() => alert(count), 1000, [count]);

  return (
    <div>
      <div>Value: {`${count}`}</div>
      <button onClick={() => setCount((c) => c + 1)}>Increment</button>
    </div>
  );
};

render(<App />);
jsx