use-debounce
Version:
Debounce hook for react
67 lines (66 loc) • 2.85 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var react_1 = require("react");
function useDebouncedCallback(callback, delay, options) {
if (options === void 0) { options = {}; }
var maxWait = options.maxWait;
var maxWaitHandler = react_1.useRef(null);
var maxWaitArgs = react_1.useRef([]);
var leading = options.leading;
var wasLeadingCalled = react_1.useRef(false);
var functionTimeoutHandler = react_1.useRef(null);
var isComponentUnmounted = react_1.useRef(false);
var debouncedFunction = react_1.useRef(callback);
debouncedFunction.current = callback;
var cancelDebouncedCallback = react_1.useCallback(function () {
clearTimeout(functionTimeoutHandler.current);
clearTimeout(maxWaitHandler.current);
maxWaitHandler.current = null;
maxWaitArgs.current = [];
functionTimeoutHandler.current = null;
wasLeadingCalled.current = false;
}, []);
react_1.useEffect(function () { return function () {
// we use flag, as we allow to call callPending outside the hook
isComponentUnmounted.current = true;
}; }, []);
var debouncedCallback = react_1.useCallback(function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
maxWaitArgs.current = args;
clearTimeout(functionTimeoutHandler.current);
if (!functionTimeoutHandler.current && leading && !wasLeadingCalled.current) {
debouncedFunction.current.apply(debouncedFunction, args);
wasLeadingCalled.current = true;
return;
}
functionTimeoutHandler.current = setTimeout(function () {
cancelDebouncedCallback();
if (!isComponentUnmounted.current) {
debouncedFunction.current.apply(debouncedFunction, args);
}
}, delay);
if (maxWait && !maxWaitHandler.current) {
maxWaitHandler.current = setTimeout(function () {
var args = maxWaitArgs.current;
cancelDebouncedCallback();
if (!isComponentUnmounted.current) {
debouncedFunction.current.apply(null, args);
}
}, maxWait);
}
}, [maxWait, delay, cancelDebouncedCallback, leading]);
var callPending = function () {
// Call pending callback only if we have anything in our queue
if (!functionTimeoutHandler.current) {
return;
}
debouncedFunction.current.apply(null, maxWaitArgs.current);
cancelDebouncedCallback();
};
// At the moment, we use 3 args array so that we save backward compatibility
return [debouncedCallback, cancelDebouncedCallback, callPending];
}
exports.default = useDebouncedCallback;