@react-hookz/web
Version:
React hooks done right, for browser and SSR.
78 lines (77 loc) • 3.05 kB
JavaScript
;
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useDebouncedCallback = void 0;
/* eslint-disable @typescript-eslint/no-explicit-any */
var react_1 = require("react");
var useUnmountEffect_1 = require("../useUnmountEffect/useUnmountEffect");
/**
* Makes passed function debounced, otherwise acts like `useCallback`.
*
* @param callback Function that will be debounced.
* @param deps Dependencies list when to update callback.
* @param delay Debounce delay.
* @param maxWait The maximum time `callback` is allowed to be delayed before
* it's invoked. 0 means no max wait.
*/
function useDebouncedCallback(callback, deps, delay, maxWait) {
if (maxWait === void 0) { maxWait = 0; }
var timeout = (0, react_1.useRef)();
var waitTimeout = (0, react_1.useRef)();
var lastCall = (0, react_1.useRef)();
var clear = function () {
if (timeout.current) {
clearTimeout(timeout.current);
timeout.current = undefined;
}
if (waitTimeout.current) {
clearTimeout(waitTimeout.current);
waitTimeout.current = undefined;
}
};
// cancel scheduled execution on unmount
(0, useUnmountEffect_1.useUnmountEffect)(clear);
return (0, react_1.useMemo)(function () {
var execute = function () {
// barely possible to test this line
/* istanbul ignore next */
if (!lastCall.current)
return;
var context = lastCall.current;
lastCall.current = undefined;
callback.apply(context.this, context.args);
clear();
};
// eslint-disable-next-line func-names
var wrapped = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (timeout.current) {
clearTimeout(timeout.current);
}
lastCall.current = { args: args, this: this };
// plan regular execution
timeout.current = setTimeout(execute, delay);
// plan maxWait execution if required
if (maxWait > 0 && !waitTimeout.current) {
waitTimeout.current = setTimeout(execute, maxWait);
}
};
Object.defineProperties(wrapped, {
length: { value: callback.length },
name: { value: "".concat(callback.name || 'anonymous', "__debounced__").concat(delay) },
});
return wrapped;
}, __spreadArray([delay, maxWait], deps, true));
}
exports.useDebouncedCallback = useDebouncedCallback;