@gilbarbara/hooks
Version:
Collection of useful React hooks
54 lines (42 loc) • 1.19 kB
text/typescript
import { useEffect, useRef, useState } from 'react';
import { useUnmount } from './useUnmount';
export function useThrottle<T extends (...arguments_: Array<any>) => void>(
callback: T,
delayMs = 500,
trailing: boolean = false,
): () => void {
const [now, setNow] = useState(0);
const callbackRef = useRef(callback);
const hasPendingCall = useRef(false);
const timer = useRef<number>(undefined);
useEffect(() => {
callbackRef.current = callback;
}, [callback]);
useEffect(() => {
if (!now) {
return;
}
if (!timer.current) {
callbackRef.current();
const timerCallback = () => {
if (hasPendingCall.current) {
hasPendingCall.current = false;
if (trailing) {
callbackRef.current();
}
timer.current = undefined;
} else {
timer.current = undefined;
}
};
timer.current = window.setTimeout(timerCallback, delayMs);
} else {
hasPendingCall.current = true;
}
}, [delayMs, now, trailing]);
useUnmount(() => {
window.clearTimeout(timer.current);
timer.current = undefined;
});
return () => setNow(Date.now());
}