Web Totals

useTimeout

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

function TimeoutComponent() {
  const [count, setCount] = useState(10);
  const { clear, reset } = useTimeout(() => setCount(0), 2000);

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

      <div>
        <button onClick={clear}>Clear Timeout</button>
      </div>

      <div>
        <button onClick={reset}>Reset Timeout</button>
      </div>
    </div>
  );
}

// Render App
render(<TimeoutComponent />);
jsx