Capítulo 56 de 80

Chapter 56: streamedQuery (Experimental)

Core Idea

streamedQuery wraps an AsyncIterable-returning function into a normal queryFn — the query goes pending until the first chunk arrives, then success (with an array of chunks-so-far), staying fetchStatus: 'fetching' until the stream ends — the building block behind chat/streaming-response UIs.

Key Concepts

  • Import: experimental_streamedQuery — still gathering feedback, name/shape may change.
  • Core option — streamFn: (context: QueryFunctionContext) => Promise<AsyncIterable<TData>>, required — receives the normal QueryFunctionContext (key, signal, etc.), returns something iterable chunk-by-chunk.
  • refetchMode (default 'reset'): controls what a refetch does to already-streamed data — 'reset' clears everything back to pending; 'append' adds new chunks onto existing data; 'replace' buffers the whole new stream and swaps it in atomically once it finishes.
  • reducer: combines each incoming chunk into the accumulated TData — defaults to array-append when TData is an array; mandatory to supply your own if TData isn't array-shaped (e.g. accumulating into a single growing string).
  • initialValue: the value shown before the first chunk arrives, and the fallback if the stream yields nothing — defaults to an empty array; required alongside a custom reducer.

Code Examples

import { experimental_streamedQuery as streamedQuery } from '@tanstack/react-query'

const chatQuery = queryOptions({
  queryKey: ['chat', conversationId],
  queryFn: streamedQuery({ streamFn: fetchChatResponseInChunks }),
})
  • What it demonstrates: wrapping a chunked async response (e.g. an LLM streaming reply) into a plain queryOptions-compatible queryFn.

Key Takeaways

  1. This is the standard building block for chat/AI-streaming-style UIs on top of TanStack Query — no custom subscription machinery needed beyond a normal useQuery.
  2. Supply a custom reducer (and initialValue) the moment the accumulated shape isn't a plain array — the default reducer only handles array accumulation.

Connects To

  • Query Functions: the QueryFunctionContext this wraps.
  • Suspense: pairs naturally with useSuspenseQuery for a chat UI that suspends until the first chunk.