UNPKG

@react-hookz/web

Version:

React hooks done right, for browser and SSR.

73 lines (72 loc) 3.12 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.useEventListener = void 0; /* eslint-disable @typescript-eslint/no-explicit-any */ var react_1 = require("react"); var __1 = require(".."); var misc_1 = require("../util/misc"); /** * Subscribes an event listener to the target, and automatically unsubscribes * it on unmount. * * @param target Element ref object or element itself. * @param params Parameters specific for target's `addEventListener`. Commonly, * it is `[eventName, listener, options]`. */ function useEventListener(target) { var params = []; for (var _i = 1; _i < arguments.length; _i++) { params[_i - 1] = arguments[_i]; } var isMounted = (0, __1.useIsMounted)(); // create static event listener var listenerRef = (0, __1.useSyncedRef)(params[1]); var eventListener = (0, react_1.useMemo)(function () { // as some event listeners designed to be used through `this` // it is better to make listener a conventional function as it // infers call context // eslint-disable-next-line func-names return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } // normally, such situation should not happen, but better to // have back covered /* istanbul ignore next */ if (!isMounted()) return; // we dont care if non-listener provided, simply dont do anything /* istanbul ignore else */ if (typeof listenerRef.current === 'function') { listenerRef.current.apply(this, args); } else if (typeof listenerRef.current.handleEvent === 'function') { listenerRef.current.handleEvent.apply(this, args); } }; }, // eslint-disable-next-line react-hooks/exhaustive-deps []); (0, react_1.useEffect)(function () { var tgt = target && (0, misc_1.hasOwnProperty)(target, 'current') ? target.current : target; if (!tgt) return; var restParams = params.slice(2); // eslint-disable-next-line @typescript-eslint/no-unsafe-argument tgt.addEventListener.apply(tgt, __spreadArray([params[0], eventListener], restParams, false)); // eslint-disable-next-line @typescript-eslint/no-unsafe-argument return function () { return tgt.removeEventListener.apply(tgt, __spreadArray([params[0], eventListener], restParams, false)); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [target, params[0]]); } exports.useEventListener = useEventListener;