Skip to content

Instantly share code, notes, and snippets.

@ChaseH88
Created June 13, 2021 14:06
Show Gist options
  • Select an option

  • Save ChaseH88/8a6eca0bbfc8c0fe8a7112b873f463a2 to your computer and use it in GitHub Desktop.

Select an option

Save ChaseH88/8a6eca0bbfc8c0fe8a7112b873f463a2 to your computer and use it in GitHub Desktop.
import { useEffect, useState, useCallback, useRef } from 'react';
const defaultOptions = {
cancelOnUnmount: true,
};
/**
* An async hook that accepts a callback function and a delay time (in milliseconds), then delays the
* execution of the given function by the defined time.
*/
const useTimeout = (fn: () => void, milliseconds: number, options = defaultOptions) => {
const opts = {
...defaultOptions,
...options || {}
};
const timeout = useRef();
const callback = useRef(fn);
const [isCleared, setIsCleared] = useState<boolean>(false);
/**
* Clears the timeout
*/
const clear = useCallback(() => {
if (timeout?.current) {
clearTimeout(timeout?.current);
setIsCleared(true);
}
}, []);
/**
* Update if function changes
*/
useEffect(() => {
if (typeof fn === 'function') {
callback.current = fn;
}
}, [fn]);
/**
* Reset if milliseconds change
*/
useEffect(() => {
if (typeof milliseconds === 'number') {
timeout.current = setTimeout(() => {
callback.current();
}, milliseconds);
}
return clear;
}, [milliseconds]);
/**
* Clean up function
*/
useEffect(() => () => {
if (opts?.cancelOnUnmount) {
clear();
}
return () => {
clear();
}
}, []);
return [isCleared, clear];
};
export { useTimeout };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment