UNPKG

@react-hookz/web

Version:

React hooks done right, for browser and SSR.

72 lines (71 loc) 3.01 kB
"use strict"; 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;