Skip to content

Instantly share code, notes, and snippets.

@dbk91
Last active November 26, 2022 03:29
Show Gist options
  • Save dbk91/45ebd7e070a5017215798284c44a70ad to your computer and use it in GitHub Desktop.
Save dbk91/45ebd7e070a5017215798284c44a70ad to your computer and use it in GitHub Desktop.
Self adjusting interval timer based on Dan Abromov's useInterval implementation.
import * as React from "react";
export default function useSelfAdjustingInterval(callback, delay) {
const target = React.useRef(delay);
const savedCallback = React.useRef<() => void>();
const startTime = React.useRef<number | null>(null);
React.useEffect(() => {
savedCallback.current = callback;
}, [callback]);
React.useEffect(() => {
let id;
function cleanup() {
if (typeof id === "number") {
clearTimeout(id);
}
}
if (delay !== null) {
if (startTime.current === null) {
startTime.current = new Date().valueOf();
}
function tick() {
if (typeof savedCallback.current !== "function" || startTime.current === null) {
return;
}
target.current += delay;
let elapsed = new Date().valueOf() - startTime.current;
let adjust = target.current - elapsed;
savedCallback.current();
id = setTimeout(tick, delay + adjust);
}
id = setTimeout(tick, delay);
return cleanup;
} else {
cleanup();
startTime.current = null;
target.current = delay;
}
}, [delay]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment