ahooks
Version:
react hooks library
138 lines • 4.44 kB
JavaScript
import { __assign, __awaiter, __generator, __read, __spreadArray } from "tslib";
import { useMemo, useState } from 'react';
import useEventListener from '../useEventListener';
import useMemoizedFn from '../useMemoizedFn';
import useRequest from '../useRequest';
import useUpdateEffect from '../useUpdateEffect';
import { getTargetElement } from '../utils/domTarget';
import { getClientHeight, getScrollHeight, getScrollTop } from '../utils/rect';
var useInfiniteScroll = function (service, options) {
if (options === void 0) {
options = {};
}
var target = options.target,
isNoMore = options.isNoMore,
_a = options.threshold,
threshold = _a === void 0 ? 100 : _a,
_b = options.reloadDeps,
reloadDeps = _b === void 0 ? [] : _b,
manual = options.manual,
onBefore = options.onBefore,
onSuccess = options.onSuccess,
onError = options.onError,
onFinally = options.onFinally;
var _c = __read(useState(), 2),
finalData = _c[0],
setFinalData = _c[1];
var _d = __read(useState(false), 2),
loadingMore = _d[0],
setLoadingMore = _d[1];
var noMore = useMemo(function () {
if (!isNoMore) return false;
return isNoMore(finalData);
}, [finalData]);
var _e = useRequest(function (lastData) {
return __awaiter(void 0, void 0, void 0, function () {
var currentData;
var _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
return [4 /*yield*/, service(lastData)];
case 1:
currentData = _c.sent();
if (!lastData) {
setFinalData(__assign(__assign({}, currentData), {
list: __spreadArray([], __read((_a = currentData.list) !== null && _a !== void 0 ? _a : []), false)
}));
} else {
setFinalData(__assign(__assign({}, currentData), {
list: __spreadArray(__spreadArray([], __read((_b = lastData.list) !== null && _b !== void 0 ? _b : []), false), __read(currentData.list), false)
}));
}
return [2 /*return*/, currentData];
}
});
});
}, {
manual: manual,
onFinally: function (_, d, e) {
setLoadingMore(false);
onFinally === null || onFinally === void 0 ? void 0 : onFinally(d, e);
},
onBefore: function () {
return onBefore === null || onBefore === void 0 ? void 0 : onBefore();
},
onSuccess: function (d) {
setTimeout(function () {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
scrollMethod();
});
onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(d);
},
onError: function (e) {
return onError === null || onError === void 0 ? void 0 : onError(e);
}
}),
loading = _e.loading,
error = _e.error,
run = _e.run,
runAsync = _e.runAsync,
cancel = _e.cancel;
var loadMore = useMemoizedFn(function () {
if (noMore) return;
setLoadingMore(true);
run(finalData);
});
var loadMoreAsync = useMemoizedFn(function () {
if (noMore) return Promise.reject();
setLoadingMore(true);
return runAsync(finalData);
});
var reload = function () {
setLoadingMore(false);
return run();
};
var reloadAsync = function () {
setLoadingMore(false);
return runAsync();
};
var scrollMethod = function () {
var el = getTargetElement(target);
if (!el) {
return;
}
el = el === document ? document.documentElement : el;
var scrollTop = getScrollTop(el);
var scrollHeight = getScrollHeight(el);
var clientHeight = getClientHeight(el);
if (scrollHeight - scrollTop <= clientHeight + threshold) {
loadMore();
}
};
useEventListener('scroll', function () {
if (loading || loadingMore) {
return;
}
scrollMethod();
}, {
target: target
});
useUpdateEffect(function () {
run();
}, __spreadArray([], __read(reloadDeps), false));
return {
data: finalData,
loading: !loadingMore && loading,
error: error,
loadingMore: loadingMore,
noMore: noMore,
loadMore: loadMore,
loadMoreAsync: loadMoreAsync,
reload: useMemoizedFn(reload),
reloadAsync: useMemoizedFn(reloadAsync),
mutate: setFinalData,
cancel: cancel
};
};
export default useInfiniteScroll;