Dynamic parallel fetching
A screen receives a changing list of record IDs and must fetch each record without a fixed number of hook calls.
TanStack · Hook
useQueries runs a dynamic array of TanStack Query queries in parallel. It returns the ordered query results by default, or a single derived value when combine is supplied.
useQueries accepts an options object containing a dynamically sized queries array. Each entry uses query options similar to useQuery; the hook executes them in parallel and normally returns results in input order. An optional combine function can transform those results into one value, while a second argument can provide a custom QueryClient.
function useQueries<T, TCombinedResult>(options: object, queryClient?: QueryClient): TCombinedResult;| Name | Type | Description |
|---|---|---|
options | object | Options object containing the queries array and optional combine and subscribed settings. |
queryClient | QueryClient | Optional custom query client supplied as the hook's top-level second argument. |
TCombinedResult: without combine, an array of query results in input order; with combine, the value returned by combine.
import { useQueries } from '@tanstack/react-query'
type Post = { id: number; title: string }
const fetchPost = async (id: number): Promise<Post> => {
const response = await fetch(`/api/posts/${id}`)
if (!response.ok) throw new Error('Request failed')
return response.json()
}
export function Posts({ ids }: { ids: number[] }) {
const results = useQueries({
queries: ids.map((id) => ({
queryKey: ['post', id],
queryFn: () => fetchPost(id),
})),
combine: (queries) => ({
posts: queries.map((query) => query.data),
pending: queries.some((query) => query.isPending),
}),
})
return <pre>{JSON.stringify(results)}</pre>
}Creates one query for every post ID and combines their results into a single object.
A screen receives a changing list of record IDs and must fetch each record without a fixed number of hook calls.
Several independently fetched values need to be exposed as one loading/data structure.
A second request depends on IDs produced by an earlier request; map those IDs into the queries array when available.
useQueries is intended for a variable number of queries. It receives an options object whose queries property is an array, allowing the array length to change without manually calling hooks in a loop.
Follow-up: How can the individual results be reduced to one value? Supply combine; its return value becomes the hook result instead of the default result array.
Without combine, the hook returns query results in the same order as the input queries array. This makes each result correspond to the query configuration at the same array position.
Follow-up: What changes when combine is supplied? The hook returns the value produced by combine rather than the ordered array.
Each queries entry is mostly like a useQuery options object, but useQueries has documented differences, including that the top-level subscribed option is not accepted per query. A custom QueryClient belongs on useQueries' second argument.
Follow-up: How would you support a changing list of IDs? Map the IDs to query option objects and pass that mapped array as queries.
useQueryqueryOptionsQueryClientParallel QueriesDependent Queries