UNPKG

ahooks

Version:
77 lines (76 loc) 3.15 kB
import debounce from 'lodash/debounce'; import { useEffect, useMemo, useRef } from 'react'; import useUpdateEffect from '../../../useUpdateEffect'; import { cancelPendingPromise } from '../utils/cancelledError'; const useDebouncePlugin = (fetchInstance, { debounceWait, debounceLeading, debounceTrailing, debounceMaxWait, ready }) => { const debouncedRef = useRef(undefined); const pendingRejectRef = useRef(undefined); const options = useMemo(() => { const ret = {}; if (debounceLeading !== undefined) { ret.leading = debounceLeading; } if (debounceTrailing !== undefined) { ret.trailing = debounceTrailing; } if (debounceMaxWait !== undefined) { ret.maxWait = debounceMaxWait; } return ret; }, [debounceLeading, debounceTrailing, debounceMaxWait]); useEffect(() => { if (debounceWait) { const _originRunAsync = fetchInstance.runAsync.bind(fetchInstance); debouncedRef.current = debounce((callback) => { callback(); }, debounceWait, options); // debounce runAsync should be promise // https://github.com/lodash/lodash/issues/4400#issuecomment-834800398 fetchInstance.runAsync = (...args) => { if (fetchInstance.options.ready === false) { return _originRunAsync(...args); } cancelPendingPromise(pendingRejectRef); return new Promise((resolve, reject) => { var _a; let callbackInvoked = false; pendingRejectRef.current = reject; (_a = debouncedRef.current) === null || _a === void 0 ? void 0 : _a.call(debouncedRef, () => { callbackInvoked = true; pendingRejectRef.current = undefined; _originRunAsync(...args) .then(resolve) .catch(reject); }); if (!callbackInvoked && options.trailing === false) { cancelPendingPromise(pendingRejectRef); } }); }; return () => { var _a; (_a = debouncedRef.current) === null || _a === void 0 ? void 0 : _a.cancel(); cancelPendingPromise(pendingRejectRef); fetchInstance.runAsync = _originRunAsync; }; } }, [debounceWait, options, fetchInstance]); useUpdateEffect(() => { var _a; if (ready === false) { (_a = debouncedRef.current) === null || _a === void 0 ? void 0 : _a.cancel(); cancelPendingPromise(pendingRejectRef); } }, [ready]); if (!debounceWait) { return {}; } return { onCancel: () => { var _a; (_a = debouncedRef.current) === null || _a === void 0 ? void 0 : _a.cancel(); cancelPendingPromise(pendingRejectRef); }, }; }; export default useDebouncePlugin;