Skip to content
masterclass BuddyTech Buzz5 fresh blogs · every Monday

TanStack · Hook

useQuery

useQuery runs and observes an asynchronous query identified by a queryKey, returning its current data, status, and error state. It integrates query-function execution with TanStack Query's caching and client configuration.

Last updated

How it works

useQuery accepts query options and returns the current query result. The query key identifies the cached request, while the query function obtains data asynchronously; changing the key can cause the query to update, and an optional QueryClient selects a custom client.

Syntax

function useQuery<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends readonly unknown[] = readonly unknown[]>(options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: QueryClient): UseQueryResult<TData, TError>

Parameters

NameTypeDescription
optionsDefinedInitialDataOptions | UndefinedInitialDataOptions | UseQueryOptionsOptions object containing queryKey, queryFn, and other query configuration.
queryClientQueryClientOptional custom client; otherwise the nearest context client is used.

Returns

A query result containing status, data, error, and convenience state flags; the exact result type depends on whether initialData is known to be defined.

Key points

  • queryKey is the identity used to locate and cache a query.
  • Changing queryKey can trigger an updated query unless the query is disabled.
  • enabled controls whether the query starts automatically and can support dependent queries.
  • staleTime defines how long fetched data remains fresh.
  • The optional QueryClient argument lets a call use a particular client instead of the nearest context client.

Common mistakes

  • The query function must resolve data or throw an error; it must not silently return an invalid result.
  • A query function cannot resolve to undefined.
  • Using an object literal with known initialData gives more precise result typing than broadly typing the options.

Example: Fetch and render todos

import { useQuery } from '@tanstack/react-query'

async function fetchTodos() {
  const response = await fetch('/api/todos')
  if (!response.ok) throw new Error('Request failed')
  return response.json() as Promise<{ id: number; title: string }[]>
}

export function TodoList() {
  const { data, isPending, isError, error } = useQuery({
    queryKey: ['todos'],
    queryFn: fetchTodos,
  })

  if (isPending) return <p>Loading…</p>
  if (isError) return <p>{error.message}</p>
  return <ul>{data.map(todo => <li key={todo.id}>{todo.title}</li>)}</ul>
}

This component declares a cached todos query and renders according to its current result state.

When to use it

Fetch server data

Load remote resources such as todo lists or user profiles while exposing loading and error states.

Dependent queries

Represent requests whose inputs depend on another value by combining enabled with a query key.

Choose a query client

Reuse a specific cache and configuration boundary by passing a custom QueryClient.

Interview questions

QWhat are the essential inputs to useQuery?

useQuery declares a query from an options object and returns its current result. The queryKey identifies the query, and queryFn performs the asynchronous request.

Follow-up: What happens when the key changes? The query automatically updates when the key changes, provided enabled is not false.

QWhat contract does queryFn have?

The query function receives a QueryFunctionContext and must return a promise that resolves the data or throws an error. It is required unless a default query function exists.

Follow-up: Can the query function resolve undefined? No; the documentation states that query data cannot be undefined.

QHow do initialData and QueryClient affect the result?

The overload with defined initialData produces a result whose data is available up front, while the ordinary overload may produce undefined data. A custom QueryClient can be supplied; otherwise the nearest context client is used.

Follow-up: Why prefer a directly written options object? It lets TypeScript infer whether initialData guarantees defined data.

  • Query Keys
  • QueryFunctionContext
  • QueryClient
  • useQueries
  • Query Options

Source: useQuery | TanStack Query React Docs. Checked 2026-11-01.