12 KiB
id, title
| id | title |
|---|---|
| useInfiniteQuery | useInfiniteQuery |
Call Signature
function useInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options, queryClient?): UseInfiniteQueryReturnType<TData, TError>;
Defined in: packages/vue-query/src/useInfiniteQuery.ts:117
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, so the resulting data is never undefined.
enabled tracks reactive dependencies automatically as a ref, a plain value, or a reactive getter
(() => ...). queryKey reacts through a ref for the array itself, or refs and reactive getters as
individual entries — the array itself can't be a bare getter.
Type Parameters
TQueryFnData
TQueryFnData
TError
TError = Error
TData
TData = InfiniteData<TQueryFnData, unknown>
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
TPageParam
TPageParam = unknown
Parameters
options
MaybeRefOrGetter<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 provided by VueQueryPlugin
will be used.
Returns
UseInfiniteQueryReturnType<TData, TError>
The same properties as useQuery, with the addition of fetchNextPage, fetchPreviousPage,
hasNextPage, hasPreviousPage, isFetchingNextPage, and isFetchingPreviousPage. data.value.pages and
data.value.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.
Example
<script setup lang="ts">
import { useInfiniteQuery } from '@tanstack/vue-query'
// `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: [] },
})
</script>
<template>
<span v-if="isError">Error: {{ error.message }}</span>
<ul>
<template v-for="page in data.pages" :key="page.nextId">
<li v-for="project in page.projects" :key="project.id">{{ project.name }}</li>
</template>
</ul>
</template>
Call Signature
function useInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options, queryClient?): UseInfiniteQueryReturnType<TData, TError>;
Defined in: packages/vue-query/src/useInfiniteQuery.ts:251
The options for useInfiniteQuery are identical to useQuery, with the addition of
initialPageParam, getNextPageParam, getPreviousPageParam, and maxPages.
enabled tracks reactive dependencies automatically as a ref, a plain value, or a reactive getter
(() => ...). queryKey reacts through a ref for the array itself, or refs and reactive getters as
individual entries — the array itself can't be a bare getter.
Type Parameters
TQueryFnData
TQueryFnData
TError
TError = Error
TData
TData = InfiniteData<TQueryFnData, unknown>
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
TPageParam
TPageParam = unknown
Parameters
options
MaybeRefOrGetter<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 provided by VueQueryPlugin
will be used.
Returns
UseInfiniteQueryReturnType<TData, TError>
The same properties as useQuery, with the addition of fetchNextPage, fetchPreviousPage,
hasNextPage, hasPreviousPage, isFetchingNextPage, and isFetchingPreviousPage. data.value.pages and
data.value.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.
Examples
Fetching the next page from a "Load More" button click:
<script setup lang="ts">
import { useInfiniteQuery } from '@tanstack/vue-query'
const {
data,
isPending,
isError,
error,
fetchNextPage,
hasNextPage,
isFetching,
isFetchingNextPage,
} = useInfiniteQuery({
queryKey: ['projects'],
queryFn: ({ pageParam }) => fetchProjects(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
})
</script>
<template>
<span v-if="isPending">Loading...</span>
<span v-else-if="isError">Error: {{ error.message }}</span>
<template v-else>
<ul>
<template v-for="page in data.pages" :key="page.nextId">
<li v-for="project in page.projects" :key="project.id">{{ project.name }}</li>
</template>
</ul>
<button @click="fetchNextPage()" :disabled="!hasNextPage || isFetching">
{{ isFetchingNextPage ? 'Loading more...' : hasNextPage ? 'Load More' : 'Nothing more to load' }}
</button>
</template>
</template>
Fetching the next page automatically as the user scrolls, using an IntersectionObserver on a
sentinel element after the list:
<script setup lang="ts">
import { onUnmounted, ref, watch } from 'vue'
import { useInfiniteQuery } from '@tanstack/vue-query'
const {
data,
isPending,
isError,
error,
fetchNextPage,
hasNextPage,
isFetching,
isFetchingNextPage,
} = useInfiniteQuery({
queryKey: ['projects'],
queryFn: ({ pageParam }) => fetchProjects(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
})
const sentinel = ref<HTMLElement>()
let observer: IntersectionObserver | undefined
watch(sentinel, (el) => {
observer?.disconnect()
if (el == null) return
observer = new IntersectionObserver(([entry]) => {
if (entry?.isIntersecting && hasNextPage.value && !isFetching.value) {
fetchNextPage()
}
})
observer.observe(el)
})
onUnmounted(() => observer?.disconnect())
</script>
<template>
<span v-if="isPending">Loading...</span>
<span v-else-if="isError">Error: {{ error.message }}</span>
<template v-else>
<ul>
<template v-for="page in data.pages" :key="page.nextId">
<li v-for="project in page.projects" :key="project.id">{{ project.name }}</li>
</template>
</ul>
<div ref="sentinel">{{ isFetchingNextPage ? 'Loading more...' : '' }}</div>
</template>
</template>
Call Signature
function useInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options, queryClient?): UseInfiniteQueryReturnType<TData, TError>;
Defined in: packages/vue-query/src/useInfiniteQuery.ts:347
Fallback overload for options whose initialData presence isn't statically known — for example, a
ref/reactive object built up conditionally, rather than a plain object literal. Prefer one of the other
overloads when possible, since they infer whether data can be undefined from initialData directly.
enabled tracks reactive dependencies automatically as a ref, a plain value, or a reactive getter
(() => ...). queryKey reacts through a ref for the array itself, or refs and reactive getters as
individual entries — the array itself can't be a bare getter.
Type Parameters
TQueryFnData
TQueryFnData
TError
TError = Error
TData
TData = InfiniteData<TQueryFnData, unknown>
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
TPageParam
TPageParam = unknown
Parameters
options
MaybeRefOrGetter<UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>>
A ref, plain value, or reactive getter resolving to the UseInfiniteQueryOptions to
use.
queryClient?
Use this to use a custom QueryClient. Otherwise, the one provided by VueQueryPlugin
will be used.
Returns
UseInfiniteQueryReturnType<TData, TError>
The same properties as useQuery, with the addition of fetchNextPage, fetchPreviousPage,
hasNextPage, hasPreviousPage, isFetchingNextPage, and isFetchingPreviousPage.
Examples
Passing a whole-options getter so maxPages reacts to a setting stored elsewhere, not just queryKey:
<script setup lang="ts">
import { useInfiniteQuery } from '@tanstack/vue-query'
const props = defineProps<{ projectId: number; maxPages: number }>()
const { data } = useInfiniteQuery(() => ({
queryKey: ['project', props.projectId, 'issues'],
queryFn: ({ pageParam }) => fetchIssues(props.projectId, pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
maxPages: props.maxPages,
}))
</script>
<template>
<template v-for="page in data?.pages" :key="page.nextId">
<li v-for="issue in page.issues" :key="issue.id">{{ issue.title }}</li>
</template>
</template>
A query that's disabled, type-safe, until postId is set — pass skipToken as queryFn instead of
setting enabled: false. This requires a whole-options getter: queryFn isn't itself reactive, so the
getter is what re-evaluates it on every change to props.postId:
<script setup lang="ts">
import { skipToken, useInfiniteQuery } from '@tanstack/vue-query'
const props = defineProps<{ 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(() => {
const postId = props.postId
return {
queryKey: ['post', postId, 'comments'],
queryFn:
postId != null
? ({ pageParam }) => fetchComments(postId, pageParam)
: skipToken,
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextId,
}
})
</script>
<template>
<span v-if="props.postId == null">Select a post</span>
<span v-else-if="isLoading">Loading...</span>
<span v-else-if="isError">Error: {{ error.message }}</span>
<ul v-else>
<template v-for="page in data.pages" :key="page.nextId">
<li v-for="comment in page.comments" :key="comment.id">{{ comment.text }}</li>
</template>
</ul>
</template>