13 KiB
id, title, redirect_from
| id | title | redirect_from | |
|---|---|---|---|
| useInfiniteQuery | useInfiniteQuery |
|
Call Signature
function useInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options, queryClient?): DefinedUseInfiniteQueryResult<TData, TError>;
Defined in: packages/react-query/src/useInfiniteQuery.ts:65
The options for useInfiniteQuery are identical to useQuery, with the addition of
initialPageParam, getNextPageParam, getPreviousPageParam, and maxPages.
This overload is selected when initialData is set.
Type Parameters
TQueryFnData
TQueryFnData
TError
TError = Error
TData
TData = InfiniteData<TQueryFnData, unknown>
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
TPageParam
TPageParam = unknown
Parameters
options
DefinedInitialDataInfiniteOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>
The DefinedInitialDataInfiniteOptions to use — everything you can pass to useInfiniteQuery, with initialData set.
queryClient?
Use this to use a custom QueryClient. Otherwise, the one from the nearest context will
be used.
Returns
DefinedUseInfiniteQueryResult<TData, TError>
The same properties as useQuery, with the addition of fetchNextPage, fetchPreviousPage,
hasNextPage, hasPreviousPage, isFetchingNextPage, and isFetchingPreviousPage. data.pages and
data.pageParams are also added, as long as a select doesn't change TData away from its default
InfiniteData<TQueryFnData> shape.
Remarks
Keep in mind that imperative fetch calls, such as fetchNextPage, may interfere with the default
refetch behavior, resulting in outdated data. Make sure to call these functions only in response to user
actions, or add conditions like hasNextPage && !isFetching.
See
infiniteQueryOptions to share these options between useInfiniteQuery and imperative APIs like queryClient.infiniteQuery.
Example
import { useInfiniteQuery } from '@tanstack/react-query'
function Projects() {
// `data` is never `undefined`, thanks to `initialData` — even if a refetch fails, so the
// list stays visible alongside the error.
const { data, isError, error } = useInfiniteQuery({
queryKey: ['projects'],
queryFn: ({ pageParam }) => fetchProjects(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
initialData: { pages: [], pageParams: [] },
})
return (
<div>
{isError ? <span>Error: {error.message}</span> : null}
<ul>
{data.pages.map((page) => page.projects.map((p) => <li key={p.id}>{p.name}</li>))}
</ul>
</div>
)
}
Call Signature
function useInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options, queryClient?): UseInfiniteQueryResult<TData, TError>;
Defined in: packages/react-query/src/useInfiniteQuery.ts:191
The options for useInfiniteQuery are identical to useQuery, with the addition of
initialPageParam, getNextPageParam, getPreviousPageParam, and maxPages.
Type Parameters
TQueryFnData
TQueryFnData
TError
TError = Error
TData
TData = InfiniteData<TQueryFnData, unknown>
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
TPageParam
TPageParam = unknown
Parameters
options
UndefinedInitialDataInfiniteOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>
The UndefinedInitialDataInfiniteOptions to use — everything you can pass to useInfiniteQuery.
queryClient?
Use this to use a custom QueryClient. Otherwise, the one from the nearest context will
be used.
Returns
UseInfiniteQueryResult<TData, TError>
The same properties as useQuery, with the addition of fetchNextPage, fetchPreviousPage,
hasNextPage, hasPreviousPage, isFetchingNextPage, and isFetchingPreviousPage. data.pages and
data.pageParams are also added, as long as a select doesn't change TData away from its default
InfiniteData<TQueryFnData> shape.
Remarks
Keep in mind that imperative fetch calls, such as fetchNextPage, may interfere with the default
refetch behavior, resulting in outdated data. Make sure to call these functions only in response to user
actions, or add conditions like hasNextPage && !isFetching.
See
infiniteQueryOptions to share these options between useInfiniteQuery and imperative APIs like queryClient.infiniteQuery.
Examples
Fetching the next page from a "Load More" button click:
import { useInfiniteQuery } from '@tanstack/react-query'
function Projects() {
const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } =
useInfiniteQuery({
queryKey: ['projects'],
queryFn: ({ pageParam }) => fetchProjects(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
})
if (isPending) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return (
<>
<ul>
{data.pages.map((page) =>
page.projects.map((project) => <li key={project.id}>{project.name}</li>),
)}
</ul>
<button
onClick={() => fetchNextPage()}
disabled={!hasNextPage || isFetching}
>
{isFetchingNextPage
? 'Loading more...'
: hasNextPage
? 'Load More'
: 'Nothing more to load'}
</button>
</>
)
}
Fetching the next page automatically as the user scrolls, using an IntersectionObserver on a
sentinel element after the list:
import { useInfiniteQuery } from '@tanstack/react-query'
import { useEffect, useRef } from 'react'
function Projects() {
const {
data,
isPending,
isError,
error,
fetchNextPage,
hasNextPage,
isFetching,
isFetchingNextPage,
} = useInfiniteQuery({
queryKey: ['projects'],
queryFn: ({ pageParam }) => fetchProjects(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
})
const sentinelRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const sentinel = sentinelRef.current
if (sentinel == null || !hasNextPage || isFetching) return
const observer = new IntersectionObserver(([entry]) => {
if (entry?.isIntersecting) fetchNextPage()
})
observer.observe(sentinel)
return () => observer.disconnect()
}, [hasNextPage, isFetching, fetchNextPage])
if (isPending) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return (
<>
<ul>
{data.pages.map((page) =>
page.projects.map((project) => <li key={project.id}>{project.name}</li>),
)}
</ul>
<div ref={sentinelRef}>{isFetchingNextPage ? 'Loading more...' : null}</div>
</>
)
}
Call Signature
function useInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options, queryClient?): UseInfiniteQueryResult<TData, TError>;
Defined in: packages/react-query/src/useInfiniteQuery.ts:347
The options for useInfiniteQuery are identical to useQuery, with the addition of
initialPageParam, getNextPageParam, getPreviousPageParam, and maxPages.
Type Parameters
TQueryFnData
TQueryFnData
TError
TError = Error
TData
TData = InfiniteData<TQueryFnData, unknown>
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
TPageParam
TPageParam = unknown
Parameters
options
UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>
The UseInfiniteQueryOptions to use — everything you can pass to useInfiniteQuery.
queryClient?
Use this to use a custom QueryClient. Otherwise, the one from the nearest context will
be used.
Returns
UseInfiniteQueryResult<TData, TError>
The same properties as useQuery, with the addition of fetchNextPage, fetchPreviousPage,
hasNextPage, hasPreviousPage, isFetchingNextPage, and isFetchingPreviousPage. data.pages and
data.pageParams are also added, as long as a select doesn't change TData away from its default
InfiniteData<TQueryFnData> shape.
Remarks
Keep in mind that imperative fetch calls, such as fetchNextPage, may interfere with the default
refetch behavior, resulting in outdated data. Make sure to call these functions only in response to user
actions, or add conditions like hasNextPage && !isFetching.
See
infiniteQueryOptions to share these options between useInfiniteQuery and imperative APIs like queryClient.infiniteQuery.
Examples
Fetching the next page from a "Load More" button click:
import { useInfiniteQuery } from '@tanstack/react-query'
function Projects() {
const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } =
useInfiniteQuery({
queryKey: ['projects'],
queryFn: ({ pageParam }) => fetchProjects(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
})
if (isPending) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return (
<>
<ul>
{data.pages.map((page) =>
page.projects.map((project) => <li key={project.id}>{project.name}</li>),
)}
</ul>
<button
onClick={() => fetchNextPage()}
disabled={!hasNextPage || isFetching}
>
{isFetchingNextPage
? 'Loading more...'
: hasNextPage
? 'Load More'
: 'Nothing more to load'}
</button>
</>
)
}
Fetching the next page automatically as the user scrolls, using an IntersectionObserver on a
sentinel element after the list:
import { useInfiniteQuery } from '@tanstack/react-query'
import { useEffect, useRef } from 'react'
function Projects() {
const {
data,
isPending,
isError,
error,
fetchNextPage,
hasNextPage,
isFetching,
isFetchingNextPage,
} = useInfiniteQuery({
queryKey: ['projects'],
queryFn: ({ pageParam }) => fetchProjects(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
})
const sentinelRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const sentinel = sentinelRef.current
if (sentinel == null || !hasNextPage || isFetching) return
const observer = new IntersectionObserver(([entry]) => {
if (entry?.isIntersecting) fetchNextPage()
})
observer.observe(sentinel)
return () => observer.disconnect()
}, [hasNextPage, isFetching, fetchNextPage])
if (isPending) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return (
<>
<ul>
{data.pages.map((page) =>
page.projects.map((project) => <li key={project.id}>{project.name}</li>),
)}
</ul>
<div ref={sentinelRef}>{isFetchingNextPage ? 'Loading more...' : null}</div>
</>
)
}
A query that's disabled, type safe, until postId is set — pass skipToken as queryFn
instead of setting enabled: false:
import { skipToken, useInfiniteQuery } from '@tanstack/react-query'
function Comments({ postId }: { postId: string | undefined }) {
// Use `isLoading`, not `isPending`, so the loading state doesn't show while the query is disabled.
const { data, isLoading, isError, error } = useInfiniteQuery({
queryKey: ['post', postId, 'comments'],
queryFn:
postId != null
? ({ pageParam }) => fetchComments(postId, pageParam)
: skipToken,
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
})
if (postId == null) return 'Select a post'
if (isLoading) return 'Loading...'
if (isError) return <span>Error: {error.message}</span>
return (
<ul>
{data?.pages.map((page) => page.comments.map((c) => <li key={c.id}>{c.text}</li>))}
</ul>
)
}