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