@@ -20,11 +20,11 @@ const initialItems = (page: number): Result => {
2020 }
2121}
2222
23- const fetchItems = async ( page : number , ts : number ) : Promise < Result > => {
23+ const fetchItems = async ( page : number , ts : number , nextId ?: any ) : Promise < Result > => {
2424 await sleep ( 10 )
2525 return {
2626 items : [ ...new Array ( 10 ) ] . fill ( null ) . map ( ( _ , d ) => page * pageSize + d ) ,
27- nextId : page + 1 ,
27+ nextId : nextId ?? page + 1 ,
2828 ts,
2929 }
3030}
@@ -1063,4 +1063,137 @@ describe('useInfiniteQuery', () => {
10631063 // ensure that Item: 4 is no longer rendered
10641064 expect ( rendered . queryAllByText ( 'Item: 4' ) ) . toHaveLength ( 0 )
10651065 } )
1066+
1067+ it ( 'should compute canFetchMore correctly for falsy getFetchMore return value on refetching' , async ( ) => {
1068+ const key = queryKey ( )
1069+ const MAX = 2
1070+
1071+ function Page ( ) {
1072+ const fetchCountRef = React . useRef ( 0 )
1073+ const [ isRemovedLastPage , setIsRemovedLastPage ] = React . useState < boolean > (
1074+ false
1075+ )
1076+ const {
1077+ status,
1078+ data,
1079+ error,
1080+ isFetching,
1081+ isFetchingMore,
1082+ fetchMore,
1083+ canFetchMore,
1084+ refetch,
1085+ } = useInfiniteQuery < Result , Error , [ string , number ] > (
1086+ key ,
1087+ ( _key , nextId = 0 ) =>
1088+ fetchItems (
1089+ nextId ,
1090+ fetchCountRef . current ++ ,
1091+ nextId === MAX || ( nextId === MAX - 1 && isRemovedLastPage )
1092+ ? false
1093+ : undefined
1094+ ) ,
1095+ {
1096+ getFetchMore : ( lastGroup , _allGroups ) => lastGroup . nextId ,
1097+ }
1098+ )
1099+
1100+ return (
1101+ < div >
1102+ < h1 > Pagination</ h1 >
1103+ { status === 'loading' ? (
1104+ 'Loading...'
1105+ ) : status === 'error' ? (
1106+ < span > Error: { error ?. message } </ span >
1107+ ) : (
1108+ < >
1109+ < div > Data:</ div >
1110+ { data ?. map ( ( page , i ) => (
1111+ < div key = { i } >
1112+ < div >
1113+ Page { i } : { page . ts }
1114+ </ div >
1115+ < div key = { i } >
1116+ { page . items . map ( item => (
1117+ < p key = { item } > Item: { item } </ p >
1118+ ) ) }
1119+ </ div >
1120+ </ div >
1121+ ) ) }
1122+ < div >
1123+ < button
1124+ onClick = { ( ) => fetchMore ( ) }
1125+ disabled = { ! canFetchMore || Boolean ( isFetchingMore ) }
1126+ >
1127+ { isFetchingMore
1128+ ? 'Loading more...'
1129+ : canFetchMore
1130+ ? 'Load More'
1131+ : 'Nothing more to load' }
1132+ </ button >
1133+ < button onClick = { ( ) => refetch ( ) } > Refetch</ button >
1134+ < button onClick = { ( ) => setIsRemovedLastPage ( true ) } >
1135+ Remove Last Page
1136+ </ button >
1137+ </ div >
1138+ < div >
1139+ { isFetching && ! isFetchingMore
1140+ ? 'Background Updating...'
1141+ : null }
1142+ </ div >
1143+ </ >
1144+ ) }
1145+ </ div >
1146+ )
1147+ }
1148+
1149+ const rendered = render ( < Page /> )
1150+
1151+ rendered . getByText ( 'Loading...' )
1152+
1153+ await waitFor ( ( ) => {
1154+ rendered . getByText ( 'Item: 9' )
1155+ rendered . getByText ( 'Page 0: 0' )
1156+ } )
1157+
1158+ fireEvent . click ( rendered . getByText ( 'Load More' ) )
1159+
1160+ await waitFor ( ( ) => rendered . getByText ( 'Loading more...' ) )
1161+
1162+ await waitFor ( ( ) => {
1163+ rendered . getByText ( 'Item: 19' )
1164+ rendered . getByText ( 'Page 0: 0' )
1165+ rendered . getByText ( 'Page 1: 1' )
1166+ } )
1167+
1168+ fireEvent . click ( rendered . getByText ( 'Load More' ) )
1169+
1170+ await waitFor ( ( ) => rendered . getByText ( 'Loading more...' ) )
1171+
1172+ await waitFor ( ( ) => {
1173+ rendered . getByText ( 'Item: 29' )
1174+ rendered . getByText ( 'Page 0: 0' )
1175+ rendered . getByText ( 'Page 1: 1' )
1176+ rendered . getByText ( 'Page 2: 2' )
1177+ } )
1178+
1179+ rendered . getByText ( 'Nothing more to load' )
1180+
1181+ fireEvent . click ( rendered . getByText ( 'Remove Last Page' ) )
1182+
1183+ await waitForMs ( 10 )
1184+
1185+ fireEvent . click ( rendered . getByText ( 'Refetch' ) )
1186+
1187+ await waitFor ( ( ) => rendered . getByText ( 'Background Updating...' ) )
1188+
1189+ await waitFor ( ( ) => {
1190+ rendered . getByText ( 'Page 0: 3' )
1191+ rendered . getByText ( 'Page 1: 4' )
1192+ } )
1193+
1194+ expect ( rendered . queryByText ( 'Item: 29' ) ) . toBeNull ( )
1195+ expect ( rendered . queryByText ( 'Page 2: 5' ) ) . toBeNull ( )
1196+
1197+ rendered . getByText ( 'Nothing more to load' )
1198+ } )
10661199} )
0 commit comments