UNPKG

@orca-fe/hooks

Version:

React Hooks Collections

210 lines (207 loc) 7.4 kB
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime"; import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator"; import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; /* eslint-disable @typescript-eslint/no-explicit-any */ import { useMemoizedFn } from 'ahooks'; import { useEffect, useRef, useState } from 'react'; var eArr = []; var loadMoreFlag = {}; export var isFetchResult = value => { if (value != null && typeof value === 'object') { if ('data' in value) { return true; } } return false; }; export var isPageResult = value => { if (value != null && typeof value === 'object') { if ('total' in value && 'list' in value && Array.isArray(value.list) && typeof value.total === 'number') { return true; } } return false; }; export function defaultFormatter(res) { var t = res; if (isFetchResult(t)) { t = t.data; } if (isPageResult(t)) { return t; } throw new Error('[useLoadMore] Service result is not a page result. Please use formatter to convert the result to `PageResultType`.'); } export function useLoadMore(_service, options = {}) { var _stateMgr$state, _stateMgr$setState, _data$list2; var _options$defaultParam = options.defaultParams, defaultParams = _options$defaultParam === void 0 ? [] : _options$defaultParam, _options$manual = options.manual, manual = _options$manual === void 0 ? false : _options$manual, _options$pageSize = options.pageSize, pageSize = _options$pageSize === void 0 ? 10 : _options$pageSize, onError = options.onError, onSuccess = options.onSuccess, _options$formatter = options.formatter, formatter = _options$formatter === void 0 ? defaultFormatter : _options$formatter, stateMgr = options.stateMgr, onFinish = options.onFinish; var service = useMemoizedFn(_service); // 组件状态控制 start var _useState = useState(() => ({ loading: false, data: { list: [], total: 0 }, page: 1, params: defaultParams })), _useState2 = _slicedToArray(_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 = useRef({ unloaded: false, ticket: 0, loading: false }).current; var setState = useMemoizedFn((newState = {}) => { if (!_this.unloaded) { _setState(state => _objectSpread(_objectSpread({}, 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, _state$page = state.page, page = _state$page === void 0 ? 1 : _state$page; // 发起请求 var load = useMemoizedFn( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(..._args) { var isLoadMore, args, pageIndex, ticket, _res, formattedData, _data$list; return _regeneratorRuntime().wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: // 取第一个参数判断是否加载更多 isLoadMore = _args[0] === loadMoreFlag; // 取得参数(如果是加载更多,需要从 state 中取得参数) args = isLoadMore ? params !== null && params !== void 0 ? params : defaultParams : _args; pageIndex = isLoadMore ? page + 1 : 1; ticket = performance.now(); _this.ticket = ticket; _this.loading = true; setState({ loading: true, error: undefined }); _context.prev = 7; _context.next = 10; return service({ pageIndex, pageSize }, ...args); case 10: _res = _context.sent; formattedData = formatter(_res); if (!(formattedData == null)) { _context.next = 14; break; } throw new Error('[useLoadMore] Formatted result is undefined'); case 14: if (_this.ticket === ticket) { // 请求结果有效 _this.loading = false; setState({ params: args, loading: false, data: isLoadMore ? { list: [...((_data$list = data === null || data === void 0 ? void 0 : data.list) !== null && _data$list !== void 0 ? _data$list : []), ...formattedData.list], total: formattedData.total } : formattedData, page: pageIndex }); if (formattedData != null) { if (typeof onSuccess === 'function') { onSuccess(formattedData, args); } } else if (typeof onError === 'function') { 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"](7); console.error(_context.t0); _this.loading = false; setState({ data: { list: [], total: 0 }, error: _context.t0, loading: false }); if (typeof onError === 'function') { onError(_context.t0, args); } case 24: return _context.abrupt("return", undefined); case 25: case "end": return _context.stop(); } }, _callee, null, [[7, 18]]); }))); var run = useMemoizedFn(load); var loadMore = useMemoizedFn( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() { return _regeneratorRuntime().wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: return _context2.abrupt("return", load(loadMoreFlag)); case 1: case "end": return _context2.stop(); } }, _callee2); }))); var cancel = useMemoizedFn(() => { _this.ticket = Date.now(); }); useEffect(() => { _this.loading = false; _this.unloaded = false; // 如果 manual === false,则需要主动加载一次 if (!manual) { load(...defaultParams); } return () => { _this.unloaded = true; }; }, []); var list = (_data$list2 = data === null || data === void 0 ? void 0 : data.list) !== null && _data$list2 !== void 0 ? _data$list2 : eArr; var total = (data === null || data === void 0 ? void 0 : data.total) || 0; return { loading, params, data: list, total, page, hasMore: list.length < total, error, run, loadMore, cancel }; } export default useLoadMore;