Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support userInfiniteScroll use forcedLoadMore to keep requestin… #2640

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 29 additions & 11 deletions packages/hooks/src/useInfiniteScroll/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,28 @@ const useInfiniteScroll = <TData extends Data>(
onSuccess,
onError,
onFinally,
forcedLoadMore = false,
} = options;

const [finalData, setFinalData] = useState<TData>();
const [loadingMore, setLoadingMore] = useState(false);

const noMore = useMemo(() => {
if (!isNoMore) return false;
return isNoMore(finalData);
const { noMore, trulyNoMore } = useMemo(() => {
if (!isNoMore)
return {
noMore: false,
trulyNoMore: false,
};
const dataIsNoMore = isNoMore(finalData);

return {
noMore: !forcedLoadMore && dataIsNoMore,
trulyNoMore: dataIsNoMore,
};
}, [finalData]);

const { loading, error, run, runAsync, cancel } = useRequest(
async (lastData?: TData) => {
async (lastData?: TData, _isNeedForcedLoadMore?: boolean) => {
const currentData = await service(lastData);
if (!lastData) {
setFinalData({
Expand All @@ -54,8 +64,12 @@ const useInfiniteScroll = <TData extends Data>(
onFinally?.(d, e);
},
onBefore: () => onBefore?.(),
onSuccess: (d) => {
onSuccess: (d, isNeedForcedLoadMore) => {
setTimeout(() => {
// if request trrigered by forced load more, is no need to check again
if (isNeedForcedLoadMore) {
return;
}
// eslint-disable-next-line @typescript-eslint/no-use-before-define
scrollMethod();
});
Expand All @@ -65,16 +79,16 @@ const useInfiniteScroll = <TData extends Data>(
},
);

const loadMore = useMemoizedFn(() => {
const loadMore = useMemoizedFn((isNeedForcedLoadMore = false) => {
if (noMore) return;
Copy link
Collaborator

@crazylxr crazylxr Sep 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我理解这个好像没那么复杂,不需要写很多复杂的逻辑,其他的逻辑都删掉,直接:

if(!isNeedForcedLoadMore && noMore) {
 return;
}

是不是就好了

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我理解这个好像没那么复杂,不需要写很多复杂的逻辑,其他的逻辑都删掉,直接:

if(!isNeedForcedLoadMore && noMore) {
 return;
}

是不是就好了

会有问题的,当滚动到下方时,如果不判断
else if (scrollHeight - scrollTop <= clientHeight) { loadMore(true); } 会导致它一直触发loadMore,需要加一层判断来确认是用户主动向下滚动,而不是考虑threshold的距离

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你又改 api 了呀,如果实现 forceLoadMore,从 api 的设计上 我认为在loadMore 的时候增加一个参数,是否忽略 noMore,比增加一个配置更好,逻辑处理也比较简单

function loadMore(ignoreNoMore: bolean) {
}

你看看呢

setLoadingMore(true);
run(finalData);
run(finalData, isNeedForcedLoadMore);
});

const loadMoreAsync = useMemoizedFn(() => {
const loadMoreAsync = useMemoizedFn((isNeedForcedLoadMore = false) => {
if (noMore) return Promise.reject();
setLoadingMore(true);
return runAsync(finalData);
return runAsync(finalData, isNeedForcedLoadMore);
});

const reload = () => {
Expand All @@ -99,8 +113,11 @@ const useInfiniteScroll = <TData extends Data>(
const scrollHeight = getScrollHeight(el);
const clientHeight = getClientHeight(el);

if (scrollHeight - scrollTop <= clientHeight + threshold) {
// when set `forcedLoadMore`, only user scroll to bottom will trrigger load more
if (!forcedLoadMore && scrollHeight - scrollTop <= clientHeight + threshold) {
loadMore();
} else if (scrollHeight - scrollTop <= clientHeight) {
loadMore(true);
}
};

Expand All @@ -125,7 +142,8 @@ const useInfiniteScroll = <TData extends Data>(
error,
loadingMore,
noMore,

/** when set `forcedLoadMore` true, `noMore` will be always true, use `trulyNoMore` to judge data whther is no more */
trulyNoMore,
loadMore,
loadMoreAsync,
reload: useMemoizedFn(reload),
Expand Down
4 changes: 3 additions & 1 deletion packages/hooks/src/useInfiniteScroll/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export interface InfiniteScrollResult<TData extends Data> {
loadingMore: boolean;
error?: Error;
noMore: boolean;

/** when set `forcedLoadMore` true, `noMore` will be always true, use `trulyNoMore` to judge data whther is no more */
trulyNoMore: boolean;
loadMore: () => void;
loadMoreAsync: () => Promise<TData>;
reload: () => void;
Expand All @@ -26,6 +27,7 @@ export interface InfiniteScrollOptions<TData extends Data> {
threshold?: number;

manual?: boolean;
forcedLoadMore?: boolean;
reloadDeps?: DependencyList;

onBefore?: () => void;
Expand Down