@react-hookz/web
Version:
React hooks done right, for browser and SSR.
72 lines (71 loc) • 3.01 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.useThrottledCallback = void 0;
/* eslint-disable @typescript-eslint/no-explicit-any */
var react_1 = require("react");
var __1 = require("..");
/**
* Makes passed function throttled, otherwise acts like `useCallback`.
*
* @param callback Function that will be throttled.
* @param deps Dependencies list when to update callback.
* @param delay Throttle delay.
* @param noTrailing If `noTrailing` is true, callback will only execute every
* `delay` milliseconds, otherwise, callback will be executed one final time
* after the last throttled-function call.
*/
function useThrottledCallback(callback, deps, delay, noTrailing) {
if (noTrailing === void 0) { noTrailing = false; }
var timeout = (0, react_1.useRef)();
var lastCall = (0, react_1.useRef)();
(0, __1.useUnmountEffect)(function () {
if (timeout.current) {
clearTimeout(timeout.current);
}
});
return (0, react_1.useMemo)(function () {
var execute = function (context, args) {
lastCall.current = undefined;
callback.apply(context, args);
timeout.current = setTimeout(function () {
timeout.current = undefined;
// if trailing execution is not disabled - call callback with last
// received arguments and context
if (!noTrailing && lastCall.current) {
execute(lastCall.current.this, lastCall.current.args);
lastCall.current = undefined;
}
}, delay);
};
// 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) {
// if we cant execute callback immediately - save its arguments and
// context to execute it when delay is passed
lastCall.current = { args: args, this: this };
return;
}
execute(this, args);
};
Object.defineProperties(wrapped, {
length: { value: callback.length },
name: { value: "".concat(callback.name || 'anonymous', "__throttled__").concat(delay) },
});
return wrapped;
// eslint-disable-next-line react-hooks/exhaustive-deps,@typescript-eslint/no-unsafe-assignment
}, __spreadArray([delay, noTrailing], deps, true));
}
exports.useThrottledCallback = useThrottledCallback;