Overview
The InfiniteQueryObserver extends QueryObserver to provide support for infinite/paginated queries. It adds methods for fetching next and previous pages and tracks pagination state.
Constructor
const observer = new InfiniteQueryObserver < TQueryFnData , TError , TData , TQueryKey , TPageParam >(
client : QueryClient ,
options : InfiniteQueryObserverOptions < TQueryFnData , TError , TData , TQueryKey , TPageParam >
)
options
InfiniteQueryObserverOptions
required
Options for the infinite query observer queryFn
QueryFunction<TQueryFnData, TQueryKey, TPageParam>
required
Function that fetches a page of data. Receives pageParam in context.
The initial page parameter
getNextPageParam
(lastPage: TQueryFnData, allPages: TQueryFnData[], lastPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined | null
required
Function to get the next page parameter. Return undefined or null if there are no more pages.
getPreviousPageParam
(firstPage: TQueryFnData, allPages: TQueryFnData[], firstPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined | null
Function to get the previous page parameter. Return undefined or null if there are no previous pages.
Maximum number of pages to store in the data
Example:
const observer = new InfiniteQueryObserver ( queryClient , {
queryKey: [ 'projects' ],
queryFn : async ({ pageParam }) => {
const response = await fetch ( `/api/projects?cursor= ${ pageParam } ` )
return response . json ()
},
initialPageParam: 0 ,
getNextPageParam : ( lastPage , allPages , lastPageParam ) => {
return lastPage . nextCursor
},
getPreviousPageParam : ( firstPage , allPages , firstPageParam ) => {
return firstPage . prevCursor
},
})
Methods
InfiniteQueryObserver inherits all methods from QueryObserver and adds:
fetchNextPage()
Fetches the next page of data.
const result = await observer . fetchNextPage (
options ?: FetchNextPageOptions
): Promise < InfiniteQueryObserverResult < TData , TError >>
Cancel currently running request before fetching next page. Defaults to true.
Throw error instead of returning it in result. Defaults to false.
Returns: Promise resolving to the infinite query result
Example:
const result = await observer . fetchNextPage ()
if ( result . hasNextPage ) {
console . log ( 'More pages available' )
}
fetchPreviousPage()
Fetches the previous page of data.
const result = await observer . fetchPreviousPage (
options ?: FetchPreviousPageOptions
): Promise < InfiniteQueryObserverResult < TData , TError >>
Cancel currently running request before fetching previous page. Defaults to true.
Throw error instead of returning it in result. Defaults to false.
Returns: Promise resolving to the infinite query result
Example:
const result = await observer . fetchPreviousPage ()
if ( result . hasPreviousPage ) {
console . log ( 'More previous pages available' )
}
subscribe()
Subscribes to infinite query updates.
const unsubscribe = observer . subscribe (
listener : ( result : InfiniteQueryObserverResult < TData , TError >) => void
): () => void
listener
(result: InfiniteQueryObserverResult<TData, TError>) => void
required
Callback function that receives infinite query results
Returns: Function to unsubscribe
getCurrentResult()
Returns the current infinite query result without subscribing.
const result = observer . getCurrentResult (): InfiniteQueryObserverResult < TData , TError >
Returns: Current infinite query result
InfiniteQueryObserverResult
Extends all properties from QueryObserverResult and adds: Show additional properties
data
InfiniteData<TData, TPageParam>
The infinite data object containing pages and pageParams Array of page parameters corresponding to each page
Is true if there is a next page to fetch
Is true if there is a previous page to fetch
Is true while fetching the next page
Is true while fetching the previous page
Is true if the query failed while fetching the next page
Is true if the query failed while fetching the previous page
fetchNextPage
(options?: FetchNextPageOptions) => Promise<InfiniteQueryObserverResult>
Function to fetch the next page
fetchPreviousPage
(options?: FetchPreviousPageOptions) => Promise<InfiniteQueryObserverResult>
Function to fetch the previous page
Type Parameters
TQueryFnData - The type of data returned by the query function for a single page
TError - The type of error that can be thrown (defaults to DefaultError)
TData - The type of data after selection/transformation
TQueryKey - The type of the query key
TPageParam - The type of the page parameter
Usage Example
import { QueryClient , InfiniteQueryObserver } from '@tanstack/query-core'
const queryClient = new QueryClient ()
interface Project {
id : number
name : string
}
interface ProjectsResponse {
projects : Project []
nextCursor ?: number
prevCursor ?: number
}
const observer = new InfiniteQueryObserver <
ProjectsResponse ,
Error ,
InfiniteData < ProjectsResponse > ,
[ 'projects' ],
number
> ( queryClient , {
queryKey: [ 'projects' ],
queryFn : async ({ pageParam }) => {
const response = await fetch ( `/api/projects?cursor= ${ pageParam } ` )
if ( ! response . ok ) throw new Error ( 'Failed to fetch' )
return response . json ()
},
initialPageParam: 0 ,
getNextPageParam : ( lastPage ) => lastPage . nextCursor ,
getPreviousPageParam : ( firstPage ) => firstPage . prevCursor ,
})
// Subscribe to updates
const unsubscribe = observer . subscribe (( result ) => {
if ( result . isLoading ) {
console . log ( 'Loading...' )
} else if ( result . isSuccess ) {
console . log ( 'Pages:' , result . data . pages . length )
console . log ( 'Has next page:' , result . hasNextPage )
// Flatten all projects
const allProjects = result . data . pages . flatMap ( page => page . projects )
console . log ( 'Total projects:' , allProjects . length )
}
})
// Load more data
if ( observer . getCurrentResult (). hasNextPage ) {
await observer . fetchNextPage ()
}
// Later, clean up
unsubscribe ()
observer . destroy ()
Infinite Data Structure
The data returned by an infinite query has a specific structure:
interface InfiniteData < TData , TPageParam > {
pages : TData [] // Array of page data
pageParams : TPageParam [] // Array of page parameters
}
Example:
// After fetching 3 pages
const result = observer . getCurrentResult ()
console . log ( result . data )
// {
// pages: [
// { projects: [...], nextCursor: 10 },
// { projects: [...], nextCursor: 20 },
// { projects: [...], nextCursor: 30 },
// ],
// pageParams: [0, 10, 20]
// }
Page Parameter Functions
The getNextPageParam and getPreviousPageParam functions determine if there are more pages to fetch:
getNextPageParam : ( lastPage , allPages , lastPageParam , allPageParams ) => {
// Return undefined/null when there are no more pages
if ( ! lastPage . nextCursor ) return undefined
return lastPage . nextCursor
}
Returning undefined or null from these functions sets hasNextPage or hasPreviousPage to false.