Skip to content

Instantly share code, notes, and snippets.

@erkobridee
Last active April 18, 2019 15:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erkobridee/c72887628400e5a7c5dd7a6b311461f3 to your computer and use it in GitHub Desktop.
Save erkobridee/c72887628400e5a7c5dd7a6b311461f3 to your computer and use it in GitHub Desktop.
import * as React from 'react';
type TFunction = (...args: any[]) => any;
/**
* safe way to use window.setTimeout using a hook to handle it
*
* @param {TFunction} callback to be executed by the timeout
* @param {number} delay time to the execution
* @param {boolean} autorun flag that says if should start running right after call the hook - default true
*
* @return {[TFunction, TFunction]} start and clear functions
*/
export function useTimeout(callback: TFunction, delay: number, autorun: boolean = true): [TFunction, TFunction] {
const savedCallback = React.useRef<TFunction>(callback);
const timeoutRef = React.useRef<number | undefined>(undefined);
const startTimeout = React.useCallback(() => {
if (timeoutRef.current || !Number(delay) || delay < 0) {
return;
}
const runOnTimeout = () => {
savedCallback.current();
timeoutRef.current = undefined;
};
timeoutRef.current = window.setTimeout(runOnTimeout, delay);
}, []);
const clearTimeout = React.useCallback(() => {
if (!timeoutRef.current) {
return;
}
window.clearTimeout(timeoutRef.current);
timeoutRef.current = undefined;
}, []);
React.useEffect(() => {
savedCallback.current = callback;
}, [callback]);
React.useEffect(() => {
if (autorun) {
clearTimeout();
startTimeout();
}
return () => clearTimeout();
}, [delay, autorun]);
return [startTimeout, clearTimeout];
}
export default useTimeout;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment