Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
You can’t perform that action at this time.