UNPKG

@orca-fe/hooks

Version:

React Hooks Collections

258 lines (252 loc) 9.97 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.UseServiceContext = void 0; exports.defaultFormatter = defaultFormatter; exports.isFetchResult = void 0; exports.useService = useService; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _regeneratorRuntime2 = _interopRequireDefault(require("@babel/runtime/helpers/regeneratorRuntime")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _ahooks = require("ahooks"); var _react = _interopRequireWildcard(require("react")); var _useInterval = _interopRequireDefault(require("./useInterval")); /* eslint-disable @typescript-eslint/no-explicit-any */ var isFetchResult = exports.isFetchResult = function isFetchResult(value) { if (value != null && (0, _typeof2.default)(value) === 'object') { if ('data' in value) { return true; } } return false; }; var UseServiceContext = exports.UseServiceContext = /*#__PURE__*/_react.default.createContext({}); var cache = {}; function defaultFormatter(res) { if (isFetchResult(res)) { return res.data; } return res; } function useService(_service) { var _stateMgr$state, _stateMgr$setState; var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var globalOptions = (0, _react.useContext)(UseServiceContext); var _globalOptions$option = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, globalOptions), options), _globalOptions$option2 = _globalOptions$option.defaultParams, defaultParams = _globalOptions$option2 === void 0 ? [] : _globalOptions$option2, initialData = _globalOptions$option.initialData, _globalOptions$option3 = _globalOptions$option.manual, manual = _globalOptions$option3 === void 0 ? false : _globalOptions$option3, onError = _globalOptions$option.onError, onSuccess = _globalOptions$option.onSuccess, cacheKey = _globalOptions$option.cacheKey, _globalOptions$option4 = _globalOptions$option.keepSuccessData, keepSuccessData = _globalOptions$option4 === void 0 ? true : _globalOptions$option4, _globalOptions$option5 = _globalOptions$option.formatter, formatter = _globalOptions$option5 === void 0 ? defaultFormatter : _globalOptions$option5, _globalOptions$option6 = _globalOptions$option.pollingInterval, pollingInterval = _globalOptions$option6 === void 0 ? 0 : _globalOptions$option6, _globalOptions$option7 = _globalOptions$option.pollingWhenHidden, pollingWhenHidden = _globalOptions$option7 === void 0 ? false : _globalOptions$option7, stateMgr = _globalOptions$option.stateMgr, onFinish = _globalOptions$option.onFinish, _globalOptions$option8 = _globalOptions$option.throwOnError, throwOnError = _globalOptions$option8 === void 0 ? true : _globalOptions$option8; var service = (0, _ahooks.useMemoizedFn)(_service); // 组件状态控制 start var _useState = (0, _react.useState)(function () { var _cache; return { loading: false, data: (_cache = cache[cacheKey !== null && cacheKey !== void 0 ? cacheKey : '']) !== null && _cache !== void 0 ? _cache : initialData, params: defaultParams }; }), _useState2 = (0, _slicedToArray2.default)(_useState, 2), __state = _useState2[0], __setState = _useState2[1]; var state = (_stateMgr$state = stateMgr === null || stateMgr === void 0 ? void 0 : stateMgr.state) !== null && _stateMgr$state !== void 0 ? _stateMgr$state : __state; var _setState = (_stateMgr$setState = stateMgr === null || stateMgr === void 0 ? void 0 : stateMgr.setState) !== null && _stateMgr$setState !== void 0 ? _stateMgr$setState : __setState; var _this = (0, _react.useRef)({ unloaded: false, ticket: 0, loading: false }).current; var setState = (0, _ahooks.useMemoizedFn)(function () { var newState = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; if (!_this.unloaded) { if (cacheKey != null && newState.data) { cache[cacheKey] = newState.data; } _setState(function (state) { return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, state), newState); }); // _setState({ ...state, ...newState }); } }); // 组件状态控制 end var _state$loading = state.loading, loading = _state$loading === void 0 ? false : _state$loading, data = state.data, error = state.error, params = state.params; var refresh = function refresh() { return Promise.resolve(); }; var visible = (0, _ahooks.useDocumentVisibility)(); // 轮询 var timer = (0, _useInterval.default)(function () { if (visible || !pollingWhenHidden) { refresh(); } }, pollingInterval || undefined); // 发起请求 var load = (0, _ahooks.useMemoizedFn)( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/(0, _regeneratorRuntime2.default)().mark(function _callee() { var ticket, _len, args, _key, _res, formattedData, _args = arguments; return (0, _regeneratorRuntime2.default)().wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: ticket = performance.now(); _this.ticket = ticket; _this.loading = true; setState({ loading: true, error: undefined }); timer.reset(); for (_len = _args.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = _args[_key]; } _context.prev = 6; _context.next = 9; return service.apply(void 0, args); case 9: _res = _context.sent; formattedData = formatter(_res); if (!(throwOnError && formattedData instanceof Error)) { _context.next = 13; break; } throw formattedData; case 13: if (keepSuccessData && formattedData == null) { formattedData = data; } if (_this.ticket === ticket) { // 请求结果有效 _this.loading = false; setState({ params: args, loading: false, data: formattedData }); if (formattedData != null) { if (typeof onSuccess === 'function') { onSuccess(formattedData, args); } } else if (typeof onError === 'function') { // 暂时禁用 onError 的触发逻辑,数据问题不做 Error 处理 // onError(new Error('result is undefined'), args); } if (typeof onFinish === 'function') { onFinish(_res, args); } } else { console.warn('Request response out date.'); } return _context.abrupt("return", formattedData); case 18: _context.prev = 18; _context.t0 = _context["catch"](6); console.error(_context.t0); if (_this.ticket === ticket) { _this.loading = false; if (keepSuccessData) { setState({ error: _context.t0, loading: false }); } else { setState({ error: _context.t0, loading: false, data: undefined }); } if (typeof onError === 'function') { onError(_context.t0, args); } } case 22: return _context.abrupt("return", undefined); case 23: case "end": return _context.stop(); } }, _callee, null, [[6, 18]]); }))); refresh = (0, _ahooks.useMemoizedFn)( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/(0, _regeneratorRuntime2.default)().mark(function _callee2() { return (0, _regeneratorRuntime2.default)().wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: if (!params) { _context2.next = 2; break; } return _context2.abrupt("return", load.apply(void 0, (0, _toConsumableArray2.default)(params))); case 2: return _context2.abrupt("return", undefined); case 3: case "end": return _context2.stop(); } }, _callee2); }))); var mutate = (0, _ahooks.useMemoizedFn)(function (data) { if (_this.unloaded) return; _setState(function (oldState) { return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, oldState), {}, { // @ts-expect-error data: typeof data === 'function' ? data(oldState.data) : data }); }); }); var cancel = (0, _ahooks.useMemoizedFn)(function () { _this.ticket = Date.now(); }); (0, _react.useEffect)(function () { _this.loading = false; _this.unloaded = false; // 如果 manual === false,则需要主动加载一次 if (!manual) { load.apply(void 0, (0, _toConsumableArray2.default)(defaultParams)); } return function () { _this.unloaded = true; }; }, []); return { loading: loading, params: params, data: data, error: error, mutate: mutate, run: load, refresh: refresh, cancel: cancel }; } var _default = exports.default = useService;