@orca-fe/hooks
Version:
React Hooks Collections
258 lines (252 loc) • 9.97 kB
JavaScript
"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;