react-interval-hook
Version:
React hook for using self-correcting setInterval, augmented by management methods (start, stop, isActive)
41 lines (40 loc) • 1.38 kB
JavaScript
import { useRef as f, useCallback as o, useEffect as x } from "react";
function h(a, t = 1e3, {
// eslint-disable-next-line @typescript-eslint/no-empty-function
onFinish: d = () => {
},
autoStart: y = !0,
immediate: m = !1,
selfCorrecting: g = !0
} = {}) {
const c = f(), r = f(!1), n = f(null), l = f(a), s = o(() => {
const e = n.current || 0;
if (g) {
const u = Date.now() - e, b = 1 + (u > 0 ? Math.floor(u / t) : 0);
n.current = e + t * b, i(Math.max(t - u, 1)), l.current(b);
} else
i(t), l.current();
}, [t]), i = o(
(e) => {
c.current !== void 0 && clearTimeout(c.current), r.current ? c.current = setTimeout(s, e) : console.debug(
"Trying to set interval timeout on inactive timer, this is no-op and probably indicates bug in your code."
);
},
[s, r]
), p = o(() => {
const e = r.current;
r.current = !0, n.current === null && (n.current = Date.now() + t), m && !e && (n.current -= t, s()), i(t);
}, [s, t, m, i]), T = o(
(e = !0) => {
const u = r.current;
c.current !== void 0 && clearTimeout(c.current), r.current = !1, c.current = void 0, n.current = null, u && e && d();
},
[d]
), v = o(() => r.current, []);
return x(() => {
l.current = a;
}, [a]), x(() => (y && p(), T), []), { start: p, stop: T, isActive: v };
}
export {
h as useInterval
};