Skip to content

Instantly share code, notes, and snippets.

@erkobridee
Created April 24, 2019 12:55
Show Gist options
  • Save erkobridee/a91347f682eb9acd2d1d90712b31a4e9 to your computer and use it in GitHub Desktop.
Save erkobridee/a91347f682eb9acd2d1d90712b31a4e9 to your computer and use it in GitHub Desktop.
react hook for safe use setInterval or setTimeout
import * as React from 'react';
export type TFunction = (...args: any[]) => any;
/**
* common code to define useTimeout or useInterval hooks
*
* @param waitFunction
* @param cleanWaitFunction
*/
function useWait(waitFunction: TFunction, cleanWaitFunction: TFunction): TFunction {
/**
* safe way to use window.setInterval or window.setTimeout using a hook to handle it
*
* @param {TFunction} callback to be executed
* @param {number} delay time
* @param {boolean} autorun flag that says if should start running right after call the hook - default true
*
* @return {[TFunction, TFunction]} start and stop functions
*/
return function(callback: TFunction, delay: number, autorun: boolean = true): [TFunction, TFunction] {
const savedCallback = React.useRef<TFunction>(callback);
const waitRef = React.useRef<number | undefined>(undefined);
const startWait = React.useCallback(() => {
if (waitRef.current || !Number(delay) || delay < 0) {
return;
}
const runOnWait = () => {
savedCallback.current();
waitRef.current = undefined;
};
waitRef.current = waitFunction(runOnWait, delay);
}, []);
const clearWait = React.useCallback(() => {
if (!waitRef.current) {
return;
}
cleanWaitFunction(waitRef.current);
waitRef.current = undefined;
}, []);
React.useEffect(() => {
savedCallback.current = callback;
}, [callback]);
React.useEffect(() => {
if (autorun) {
clearWait();
startWait();
}
return () => clearWait();
}, [delay, autorun]);
return [startWait, clearWait];
};
}
export const useInterval = useWait(window.setInterval, window.clearInterval);
export const useTimeout = useWait(window.setTimeout, window.clearTimeout);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment