@@ -27,42 +27,41 @@ export const useInfiniteVirtualization = ({
27
27
rows,
28
28
totalRecordsCount,
29
29
} : UseInfiniteVirtualizationProps ) : UseInfiniteVirtualizationReturn => {
30
- // Keep track of which pages are loaded
31
30
const [ loadedPages , setLoadedPages ] = useState < LoadedRowsCache > ( { } ) ;
32
-
33
- // Keep track of the last loaded page for appending new data
34
31
const lastLoadedPageRef = useRef < number > ( 0 ) ;
32
+ const hasMoreDataRef = useRef < boolean > ( true ) ; // Track if more data is available
35
33
36
- // Calculate max possible pages based on total records
37
34
const maxPages = useMemo ( ( ) => {
38
35
if ( ! totalRecordsCount ) return Infinity ;
39
36
40
37
return Math . ceil ( totalRecordsCount / pageSize ) ;
41
38
} , [ totalRecordsCount , pageSize ] ) ;
42
39
43
- // Effect to handle new data
44
40
useEffect ( ( ) => {
45
41
if ( rows . length > 0 ) {
46
- // Since we know we get pageSize number of rows each time (except possibly last page)
47
- // we can calculate the current page index
48
42
const currentPageIndex = lastLoadedPageRef . current ;
49
43
50
- // Store the current page of rows in cache
51
44
setLoadedPages ( ( prev ) => ( {
52
45
...prev ,
53
46
[ currentPageIndex ] : rows ,
54
47
} ) ) ;
55
48
56
- // Increment the last loaded page counter for next load
57
- lastLoadedPageRef . current = currentPageIndex + 1 ;
49
+ // Only increment if we got a full page or some data
50
+ if ( rows . length === pageSize ) {
51
+ lastLoadedPageRef . current = currentPageIndex + 1 ;
52
+ } else if ( rows . length < pageSize && rows . length > 0 ) {
53
+ // If we got less than a full page, assume this is the last page
54
+ hasMoreDataRef . current = false ;
55
+ }
56
+ } else if ( rows . length === 0 && lastLoadedPageRef . current > 0 ) {
57
+ // If no rows are returned and we've loaded at least one page, assume end of data
58
+ hasMoreDataRef . current = false ;
58
59
}
59
60
} , [ rows , pageSize ] ) ;
60
61
61
- // Memoize the combined rows from cache
62
62
const cachedRows = useMemo ( ( ) => {
63
63
const allRows : ReactTableRowType < Record < string , unknown > > [ ] = [ ] ;
64
64
65
- // Add all rows from cache in order
66
65
Object . keys ( loadedPages )
67
66
. map ( Number )
68
67
. sort ( ( a , b ) => a - b )
@@ -77,25 +76,29 @@ export const useInfiniteVirtualization = ({
77
76
( index : number ) => {
78
77
const pageIndex = Math . floor ( index / pageSize ) ;
79
78
80
- // Consider items loaded if we've reached max pages or if the page is already loaded
81
- return pageIndex >= maxPages || pageIndex < lastLoadedPageRef . current ;
79
+ return (
80
+ pageIndex >= maxPages ||
81
+ pageIndex < lastLoadedPageRef . current ||
82
+ ! hasMoreDataRef . current
83
+ ) ;
82
84
} ,
83
85
[ pageSize , maxPages ] ,
84
86
) ;
85
87
86
- // const itemCount = useMemo(() => {
87
- // return totalRecordsCount || cachedRows.length;
88
- // }, [totalRecordsCount, cachedRows.length]);
88
+ const itemCount = useMemo ( ( ) => {
89
+ // If we know there's no more data, cap itemCount at cachedRows.length
90
+ if ( ! hasMoreDataRef . current ) {
91
+ return cachedRows . length ;
92
+ }
93
+
94
+ return totalRecordsCount || cachedRows . length ;
95
+ } , [ totalRecordsCount , cachedRows . length ] ) ;
89
96
90
97
const loadMoreItems = useCallback (
91
98
async ( startIndex : number , stopIndex : number ) => {
92
- if ( ! isLoading ) {
99
+ if ( ! isLoading && hasMoreDataRef . current ) {
93
100
const targetPage = Math . floor ( stopIndex / pageSize ) ;
94
101
95
- // Only load if:
96
- // 1. We haven't loaded this page yet
97
- // 2. We haven't reached the max number of pages
98
- // 3. We're not currently loading
99
102
if ( targetPage >= lastLoadedPageRef . current && targetPage < maxPages ) {
100
103
loadMore ( ) ;
101
104
}
@@ -108,7 +111,7 @@ export const useInfiniteVirtualization = ({
108
111
109
112
return {
110
113
isItemLoaded,
111
- itemCount : totalRecordsCount || Infinity ,
114
+ itemCount,
112
115
loadMoreItems,
113
116
cachedRows,
114
117
} ;
0 commit comments