Skip to content

useSuspenseQuery

import { useSuspenseQuery } from '@effector-tanstack-query/react'
function Component() {
const { data, isFetching, refresh } = useSuspenseQuery(query)
// `data` is non-nullable (Suspense absorbs pending); `isFetching` flips
// true during background refetches.
return (
<div>
<h1>{data.name}</h1>
{isFetching && <span>refreshing…</span>}
</div>
)
}

Wrap with <Suspense> and <ErrorBoundary>:

<ErrorBoundary fallback={(e) => <p>Error: {e.message}</p>}>
<Suspense fallback={<p>Loading…</p>}>
<Component />
</Suspense>
</ErrorBoundary>

Behavior

  • 'pending' → throws observer.fetchOptimistic(observer.options) — a promise deduplicated by queryHash.
  • 'error' → throws the error (caught by ErrorBoundary).
  • 'success' → returns the result object with data: TData (non-nullable).
  • Cache hit → returns immediately, doesn’t suspend.

The hook returns the same shape as useQuery, but with the static guarantees of the Suspense gate baked into the types — data can’t be undefined, isPending is always false, isError is always false.

Return value

FieldTypeDescription
dataTDataNon-nullable
errorTError | nullAlways null past the Suspense gate
status'success'
isPendingfalse
isSuccesstrue
isErrorfalse
isFetchingbooleantrue during background refetch
isPlaceholderDataboolean
fetchStatus'fetching' | 'paused' | 'idle'
refresh() => voidInvalidates and refetches

Type signature

function useSuspenseQuery<TData, TError = Error>(
query: QueryResult<TData, TError>,
): UseSuspenseQueryResult<TData, TError>

Subscription

The hook subscribes to observer notifications via a forced re-render (so background refetches refresh the UI) AND calls query.mounted() / query.unmounted() for compatibility with concurrent useQuery consumers reading the same query through scope.

See the Suspense guide for details.