memorium/lib/hooks/useThrottledCallback.ts

56 lines
1.1 KiB
TypeScript

import { useEffect, useState } from "preact/hooks";
type ThrottleOptions = {
leading?: boolean;
trailing?: boolean;
};
const useThrottledCallback = (
callback: (...args: any[]) => void,
delay: number,
options: ThrottleOptions = {},
) => {
const { leading = true, trailing = true } = options;
const [lastExecTime, setLastExecTime] = useState(0);
const [timer, setTimer] = useState<number | null>(null);
const [isLeading, setIsLeading] = useState(false);
useEffect(() => {
return () => {
if (timer) {
clearTimeout(timer);
}
};
}, [timer]);
const throttledCallback = (...args: any[]) => {
const now = Date.now();
if (leading && !isLeading) {
callback(...args);
setLastExecTime(now);
setIsLeading(true);
}
if (trailing) {
if (timer) {
clearTimeout(timer);
}
setTimer(setTimeout(() => {
if (now - lastExecTime >= delay) {
callback(...args);
setLastExecTime(now);
}
setIsLeading(false);
}, delay));
}
};
return throttledCallback;
};
export default useThrottledCallback;