Skip to content

Instantly share code, notes, and snippets.

@mattrossman
Created April 12, 2024 21:09
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 mattrossman/7b94452ed42fd7be325e7cf39360062f to your computer and use it in GitHub Desktop.
Save mattrossman/7b94452ed42fd7be325e7cf39360062f to your computer and use it in GitHub Desktop.
useRandomInterval
import { useCallback, useEffect, useRef } from "react";
const random = (min: number, max: number) =>
Math.floor(Math.random() * (max - min)) + min;
/**
* https://www.joshwcomeau.com/snippets/react-hooks/use-random-interval/
*/
type UseRandomIntervalOptions = {
callback: () => void | Promise<void>;
enabled?: boolean;
minDelay: number;
maxDelay: number;
};
export function useRandomInterval({
callback,
enabled = true,
minDelay,
maxDelay,
}: UseRandomIntervalOptions) {
const timeoutId = useRef<number | undefined>();
const savedCallback = useRef(callback);
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
useEffect(() => {
if (enabled) {
const handleTick = () => {
const nextTickAt = random(minDelay, maxDelay);
timeoutId.current = window.setTimeout(() => {
void savedCallback.current();
handleTick();
}, nextTickAt);
};
handleTick();
}
return () => window.clearTimeout(timeoutId.current);
}, [minDelay, maxDelay, enabled]);
const cancel = useCallback(() => {
window.clearTimeout(timeoutId.current);
}, []);
return cancel;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment