Suspense-driven loading
A component needs fetched data before it can render its main content.
TanStack · Hook
useSuspenseQuery fetches query data through React Suspense instead of exposing a disabled or loading state. It returns a useQuery-like result with data guaranteed to be defined.
useSuspenseQuery is the Suspense-specific form of useQuery. It accepts query options and an optional QueryClient, suspends rendering while required data loads, and returns a result whose data is defined; loading and error handling are delegated to Suspense and error boundaries.
function useSuspenseQuery<TQueryFnData, TError, TData, TQueryKey>(options: UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: QueryClient): UseSuspenseQueryResult<TData, TError>;| Name | Type | Description |
|---|---|---|
options | UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey> | Configuration for the query, using UseSuspenseQueryOptions; it follows useQuery options except for throwOnError, enabled, and placeholderData. |
queryClient | QueryClient | Optional client used to access the query cache and configuration. |
UseSuspenseQueryResult<TData, TError>: the useQuery result shape with defined data, no isPlaceholderData, and status limited to success or error.
import { Suspense } from 'react'
import { useSuspenseQuery } from '@tanstack/react-query'
function Todos() {
const { data } = useSuspenseQuery({
queryKey: ['todos'],
queryFn: async () => {
const response = await fetch('/api/todos')
if (!response.ok) throw new Error('Request failed')
return response.json() as Promise<{ id: number; title: string }[]>
},
})
return <ul>{data.map(todo => <li key={todo.id}>{todo.title}</li>)}</ul>
}
export function App() {
return <Suspense fallback={<p>Loading…</p>}><Todos /></Suspense>
}Fetches todos while React Suspense supplies the loading boundary; the hook returns defined data when Todos renders.
A component needs fetched data before it can render its main content.
An application uses React error boundaries for query failures.
A TanStack Router application needs query data involved in SSR or streaming.
It has the same options as useQuery except throwOnError, enabled, and placeholderData. Suspense controls loading, while errors are handled through an error boundary or explicit error throwing.
Follow-up: How does its result differ from useQuery? Data is guaranteed to be defined, isPlaceholderData is absent, and status is success or error.
The hook suspends when data is needed, so the component should be rendered under a React Suspense boundary. The boundary supplies the fallback while the query resolves.
Follow-up: What happens to loading flags? The Suspense boundary replaces the component's loading-state handling rather than requiring an enabled/loading branch.
Its signature accepts UseSuspenseQueryOptions and an optional QueryClient, and returns UseSuspenseQueryResult. The returned data has type TData and is guaranteed to be defined.
Follow-up: Can the query be disabled with skipToken? No; Suspense hooks cannot represent a disabled state, so a query function must be available.
useQueryuseSuspenseInfiniteQueryuseSuspenseQueriesQueryClientUseSuspenseQueryOptionsUseSuspenseQueryResult