Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/TanStack/query/llms.txt

Use this file to discover all available pages before exploring further.

The InfiniteQueryObserver extends QueryObserver to provide additional functionality for infinite queries (pagination). It powers hooks like useInfiniteQuery.

Constructor

Creates a new InfiniteQueryObserver instance.
const observer = new InfiniteQueryObserver<TQueryFnData, TError, TData, TQueryKey, TPageParam>(
  client: QueryClient,
  options: InfiniteQueryObserverOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>
)
client
QueryClient
required
The QueryClient instance to use.
options
InfiniteQueryObserverOptions
required
Options for the infinite query observer.

Example

import { InfiniteQueryObserver } from '@tanstack/query-core'

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) => lastPage.nextCursor,
  getPreviousPageParam: (firstPage, allPages, firstPageParam) => firstPage.prevCursor,
})

Methods

InfiniteQueryObserver inherits all methods from QueryObserver and adds the following:

fetchNextPage

Fetches the next page of data.
fetchNextPage(
  options?: FetchNextPageOptions
): Promise<InfiniteQueryObserverResult<TData, TError>>
options
FetchNextPageOptions
Options for fetching the next page.
Promise<InfiniteQueryObserverResult>
Promise
Returns a promise that resolves with the infinite query result.

Example

const result = await observer.fetchNextPage()
console.log('Has next page:', result.hasNextPage)
console.log('All pages:', result.data.pages)

fetchPreviousPage

Fetches the previous page of data.
fetchPreviousPage(
  options?: FetchPreviousPageOptions
): Promise<InfiniteQueryObserverResult<TData, TError>>
options
FetchPreviousPageOptions
Options for fetching the previous page.
Promise<InfiniteQueryObserverResult>
Promise
Returns a promise that resolves with the infinite query result.

Example

const result = await observer.fetchPreviousPage()
console.log('Has previous page:', result.hasPreviousPage)

subscribe

Subscribes to the observer. Same as QueryObserver but with InfiniteQueryObserverResult.
subscribe(
  listener: (result: InfiniteQueryObserverResult<TData, TError>) => void
): () => void
listener
(result: InfiniteQueryObserverResult<TData, TError>) => void
required
Function called when the query result changes.
() => void
function
Returns an unsubscribe function.

Example

const unsubscribe = observer.subscribe((result) => {
  console.log('Pages:', result.data?.pages)
  console.log('Page params:', result.data?.pageParams)
  console.log('Has next page:', result.hasNextPage)
  console.log('Has previous page:', result.hasPreviousPage)
  console.log('Is fetching next page:', result.isFetchingNextPage)
})

unsubscribe()

getCurrentResult

Returns the current infinite query result.
getCurrentResult(): InfiniteQueryObserverResult<TData, TError>
InfiniteQueryObserverResult
InfiniteQueryObserverResult
Returns the current infinite query result.

setOptions

Updates the observer options. Automatically sets the infinite query behavior.
setOptions(
  options: InfiniteQueryObserverOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>
): void
options
InfiniteQueryObserverOptions
required
New options for the observer.

getOptimisticResult

Returns an optimistic infinite query result.
getOptimisticResult(
  options: DefaultedInfiniteQueryObserverOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>
): InfiniteQueryObserverResult<TData, TError>

InfiniteData Structure

The data returned by an infinite query has a special structure:
interface InfiniteData<TData, TPageParam> {
  pages: TData[]
  pageParams: TPageParam[]
}

Example

const result = observer.getCurrentResult()

if (result.data) {
  // Access all pages
  result.data.pages.forEach((page, index) => {
    console.log(`Page ${index}:`, page)
    console.log(`Page param:`, result.data.pageParams[index])
  })
  
  // Flatten all items from all pages
  const allItems = result.data.pages.flatMap(page => page.items)
}

Usage Example

Here’s a complete example:
import { QueryClient, InfiniteQueryObserver } from '@tanstack/query-core'

const queryClient = new QueryClient()

const observer = new InfiniteQueryObserver(queryClient, {
  queryKey: ['projects'],
  queryFn: async ({ pageParam }) => {
    const response = await fetch(
      `/api/projects?cursor=${pageParam}&limit=10`
    )
    return response.json()
  },
  initialPageParam: 0,
  getNextPageParam: (lastPage, allPages, lastPageParam) => {
    // Return undefined if no more pages
    return lastPage.nextCursor ?? undefined
  },
  getPreviousPageParam: (firstPage, allPages, firstPageParam) => {
    return firstPage.prevCursor ?? undefined
  },
})

const unsubscribe = observer.subscribe((result) => {
  if (result.isLoading) {
    console.log('Loading first page...')
  } else if (result.isError) {
    console.error('Error:', result.error)
  } else if (result.isSuccess) {
    console.log('Total pages loaded:', result.data.pages.length)
    
    if (result.hasNextPage && !result.isFetchingNextPage) {
      // Automatically fetch next page
      observer.fetchNextPage()
    }
  }
  
  if (result.isFetchingNextPage) {
    console.log('Loading more...')
  }
})

// Clean up
unsubscribe()
observer.destroy()

Differences from QueryObserver

  1. Data Structure: Returns InfiniteData<TData, TPageParam> instead of TData
  2. Additional Methods: fetchNextPage() and fetchPreviousPage()
  3. Additional Result Properties: hasNextPage, hasPreviousPage, isFetchingNextPage, etc.
  4. Required Options: Requires initialPageParam, getNextPageParam
  5. Automatic Behavior: Automatically applies infinite query behavior

Page Management

You can control the number of pages kept in memory using the maxPages option:
const observer = new InfiniteQueryObserver(queryClient, {
  queryKey: ['projects'],
  queryFn: fetchProjects,
  initialPageParam: 0,
  getNextPageParam: (lastPage) => lastPage.nextCursor,
  maxPages: 3, // Only keep 3 pages in memory
})
When maxPages is set, the oldest pages will be removed as new pages are fetched.

Build docs developers (and LLMs) love