Skip to content

Instantly share code, notes, and snippets.

@will-t-harris
Created October 30, 2020 07:39
Show Gist options
  • Save will-t-harris/7eeb673a38094d44d9621ddf92cef907 to your computer and use it in GitHub Desktop.
Save will-t-harris/7eeb673a38094d44d9621ddf92cef907 to your computer and use it in GitHub Desktop.
React useTimeout
/** Takes a callback and a delay, and deals with clearing timeouts as the callback value changes */
export const useTimeout = (callback: () => void, delay: number | null) => {
// Hook found in this SO post
// https://stackoverflow.com/questions/53090432/react-hooks-right-way-to-clear-timeouts-and-intervals/53090848
const timeoutRef = useRef<number>(0);
const callbackRef = useRef<() => void>(callback);
// Remember the latest callback:
// Without this, if you change the callback, when setTimeout kicks in, it
// will still call your old callback.
// If you add `callback` to useEffect's deps, it will work fine but the
// timeout will be reset.
useEffect(() => {
callbackRef.current = callback;
}, [callback]);
// Set up the timeout:
useEffect(() => {
if (typeof delay === 'number') {
timeoutRef.current = window.setTimeout(
() => callbackRef.current(),
delay
);
// Clear timeout if the components is unmounted or the delay changes:
return () => window.clearTimeout(timeoutRef.current);
} else {
return;
}
}, [delay]);
// In case you want to manually clear the timeout from the consuming component...:
return timeoutRef;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment