@lesnoypudge/utils-react
Version:
lesnoypudge's utils-react
54 lines (53 loc) • 1.75 kB
JavaScript
import { useState, useRef } from "react";
import { useFunction } from "../useFunction/useFunction.js";
import { useLatest } from "../useLatest/useLatest.js";
import { useUnmountEffect } from "../useUnmountEffect/useUnmountEffect.js";
import { noop } from "@lesnoypudge/utils";
const useThrottle = (options = {}) => {
const [isThrottling, setIsThrottling] = useState(false);
const isThrottlingRef = useRef(isThrottling);
const timeoutRef = useRef();
const isCalledDuringThrottleRef = useRef(false);
const lastArgsRef = useRef();
const lastFunctionRef = useRef(noop);
const lastOptionsRef = useLatest(options);
const shouldUpdateState = !lastOptionsRef.current.stateless;
const throttle = useFunction((callback, delay) => {
lastFunctionRef.current = callback;
const throttleWork = (...args) => {
lastFunctionRef.current(...args);
shouldUpdateState && setIsThrottling(true);
isThrottlingRef.current = true;
timeoutRef.current = setTimeout(() => {
if (!isCalledDuringThrottleRef.current) {
shouldUpdateState && setIsThrottling(false);
isThrottlingRef.current = false;
return;
}
throttleWork(...lastArgsRef.current);
isCalledDuringThrottleRef.current = false;
lastArgsRef.current = null;
}, delay);
};
return (...args) => {
if (isThrottlingRef.current) {
isCalledDuringThrottleRef.current = true;
lastArgsRef.current = args;
return;
}
throttleWork(...args);
};
});
useUnmountEffect(() => {
clearTimeout(timeoutRef.current);
});
return {
isThrottling,
isThrottlingRef,
throttle
};
};
export {
useThrottle
};
//# sourceMappingURL=useThrottle.js.map