import React, { useEffect, useState, useRef, forwardRef, useImperativeHandle } from 'react'; import { List } from 'antd'; import InfiniteScroll from 'react-infinite-scroll-component'; import { request } from '@/utils/request'; import PageEmpty from '@/components/Empty/PageEmpty' import PageLoading from '@/components/Empty/PageLoading' const PAGE_SIZE = 20; interface ApiResponse { items?: T[]; page: { page: number; pagesize: number; total: number; hasnext: boolean; }; } export interface PageScrollListRef { refresh: () => void; } interface PageScrollListProps> { url: string; renderItem: (item: T) => React.ReactNode; query?: Q; column?: number; className?: string; needLoading?: boolean; } const PageScrollList = forwardRef(>({ renderItem, query, url, column = 4, className = '', needLoading = true, }: PageScrollListProps, ref: React.Ref) => { useImperativeHandle(ref, () => ({ refresh, })); const [loading, setLoading] = useState(false); const [data, setData] = useState([]); const [page, setPage] = useState(1); const [hasMore, setHasMore] = useState(true); const scrollRef = useRef(null); const loadMoreData = (flag?: boolean) => { if (!flag && (loading || !hasMore)) { return; } setLoading(true); request.get(url, { page: page, pagesize: PAGE_SIZE, ...(query||{}), }) .then((res) => { const response = res as ApiResponse; const results = Array.isArray(response.items) ? response.items : Array.isArray(response) ? response as T[] : []; if (flag) { setData(results); } else { setData(data.concat(results)); } setPage(response.page.page + 1); setHasMore(response.page?.hasnext); setLoading(false); console.log(`${results.length} more items loaded!`); }) .catch(() => { setLoading(false); setHasMore(false); console.error('Failed to load data'); }) .finally(() => { setLoading(false); }); }; // 刷新列表数据 const refresh = () => { setPage(1); setHasMore(true); setData([]); } useEffect(() => { refresh() }, [query]); useEffect(() => { if (page === 1 && hasMore && data.length === 0) { loadMoreData(true); } }, [page, hasMore, data]) return ( <>
: false} // endMessage={It is all, nothing more 🤐} scrollableTarget="scrollableDiv" className='rb:h-full!' > {data.length > 0 ? ( ( {renderItem(item)} )} /> ) : !loading ? : null}
); }) as , Q = Record>(props: PageScrollListProps & { ref?: React.Ref }) => React.ReactElement; export default PageScrollList;