Skip to main content

useQuery

The useQuery hook is the primary way to fetch and cache data in TanStack Query. It subscribes to a query and returns the current state of the query.

Import

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

Signature

function useQuery<
  TQueryFnData = unknown,
  TError = DefaultError,
  TData = TQueryFnData,
  TQueryKey extends QueryKey = QueryKey,
>(
  options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
  queryClient?: QueryClient,
): UseQueryResult<TData, TError>

Type Parameters

TQueryFnData
type
default:"unknown"
The type of data returned by the query function
TError
type
default:"DefaultError"
The type of error that can be thrown by the query function
TData
type
default:"TQueryFnData"
The type of data returned by the select function (if provided), otherwise same as TQueryFnData
TQueryKey
type
default:"QueryKey"
The type of the query key

Parameters

options
UseQueryOptions
required
Configuration options for the query
queryKey
TQueryKey
required
A unique key for the query. Must be an array.
queryFn
QueryFunction<TQueryFnData, TQueryKey>
The function that will be called to fetch data. Receives a QueryFunctionContext object.
enabled
boolean
default:"true"
Set to false to disable automatic query execution
staleTime
number | ((query: Query) => number)
default:"0"
Time in milliseconds after data is considered stale. Set to Infinity to disable automatic refetching.
gcTime
number
default:"300000"
Time in milliseconds that unused/inactive cache data remains in memory. When a query’s cache becomes unused or inactive, that cache data will be garbage collected after this duration.
refetchInterval
number | false | ((query: Query) => number | false)
default:"false"
If set to a number, the query will continuously refetch at this frequency in milliseconds
refetchIntervalInBackground
boolean
default:"false"
If set to true, the query will continue to refetch while the window is in the background
refetchOnWindowFocus
boolean | 'always' | ((query: Query) => boolean | 'always')
default:"true"
If set to true, the query will refetch on window focus if the data is stale
refetchOnMount
boolean | 'always' | ((query: Query) => boolean | 'always')
default:"true"
If set to true, the query will refetch on mount if the data is stale
refetchOnReconnect
boolean | 'always' | ((query: Query) => boolean | 'always')
default:"true"
If set to true, the query will refetch on reconnect if the data is stale
retry
boolean | number | (failureCount: number, error: TError) => boolean
default:"3"
Number of retry attempts or function to determine if a request should be retried
retryDelay
number | (retryAttempt: number, error: TError) => number
Function that receives a retry attempt number and returns the delay to apply before the next attempt
select
(data: TQueryFnData) => TData
Function to transform or select a part of the data returned by the query function
initialData
TQueryFnData | () => TQueryFnData
If set, this value will be used as the initial data for the query (as long as the query hasn’t been created or cached yet)
initialDataUpdatedAt
number | (() => number | undefined)
If set, this value will be used as the time (in milliseconds) of when the initialData itself was last updated
placeholderData
TQueryFnData | (previousData: TData | undefined, previousQuery: Query | undefined) => TQueryFnData
If set, this value will be used as the placeholder data for this particular query observer while the query is still in the pending state
structuralSharing
boolean | (oldData: unknown, newData: unknown) => unknown
default:"true"
Set this to false to disable structural sharing between query results
throwOnError
boolean | (error: TError, query: Query) => boolean
default:"false"
Set this to true if you want errors to be thrown in the render phase and propagate to the nearest error boundary
networkMode
'online' | 'always' | 'offlineFirst'
default:"'online'"
Controls when the query function is allowed to execute
notifyOnChangeProps
Array<keyof UseQueryResult> | 'all'
If set, the component will only re-render when one of the listed properties change
meta
Record<string, unknown>
Optional metadata that can be used by query client plugins
subscribed
boolean
default:"true"
Set this to false to unsubscribe this observer from updates to the query cache
queryClient
QueryClient
Optional QueryClient instance to use. If not provided, the client from the nearest QueryClientProvider will be used.

Returns

data
TData
The data returned by the query function (or undefined if the query hasn’t successfully fetched yet)
error
TError | null
The error object for the query, if an error occurred
status
'pending' | 'error' | 'success'
The status of the query:
  • pending: The query has no data yet
  • error: The query encountered an error
  • success: The query was successful and data is available
fetchStatus
'fetching' | 'paused' | 'idle'
The fetch status of the query:
  • fetching: The query is currently fetching
  • paused: The query wanted to fetch, but it is paused
  • idle: The query is not fetching
isPending
boolean
Derived from status. Will be true if the query is in pending status
isSuccess
boolean
Derived from status. Will be true if the query is in success status
isError
boolean
Derived from status. Will be true if the query is in error status
isFetching
boolean
Derived from fetchStatus. Will be true whenever the query is fetching (including background refetching)
isLoading
boolean
Shorthand for isPending && isFetching - useful for showing a loading spinner on initial load
isLoadingError
boolean
Will be true if the query failed while fetching for the first time
isRefetchError
boolean
Will be true if the query failed while refetching
isStale
boolean
Will be true if the data in the cache is invalidated or if the data is older than the given staleTime
isPlaceholderData
boolean
Will be true if the data shown is placeholder data
refetch
(options?: { throwOnError?: boolean, cancelRefetch?: boolean }) => Promise<UseQueryResult>
Function to manually refetch the query
dataUpdatedAt
number
Timestamp of when the data was last updated
errorUpdatedAt
number
Timestamp of when the error was last updated
failureCount
number
The failure count for the query
failureReason
TError | null
The failure reason for the query retry

Examples

Basic Usage

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

function TodoList() {
  const { data, isPending, isError, error } = useQuery({
    queryKey: ['todos'],
    queryFn: async () => {
      const response = await fetch('/api/todos')
      if (!response.ok) {
        throw new Error('Network response was not ok')
      }
      return response.json()
    },
  })

  if (isPending) return <div>Loading...</div>
  if (isError) return <div>Error: {error.message}</div>

  return (
    <ul>
      {data.map((todo) => (
        <li key={todo.id}>{todo.title}</li>
      ))}
    </ul>
  )
}

With Type Safety

interface Todo {
  id: number
  title: string
  completed: boolean
}

function TodoList() {
  const { data } = useQuery<Todo[], Error>({
    queryKey: ['todos'],
    queryFn: async () => {
      const response = await fetch('/api/todos')
      return response.json()
    },
  })

  // data is typed as Todo[] | undefined
}

With Data Transformation

function TodoList() {
  const { data } = useQuery({
    queryKey: ['todos'],
    queryFn: fetchTodos,
    select: (data) => data.filter((todo) => !todo.completed),
  })

  // Only incomplete todos are returned
}

Conditional Queries

function User({ userId }: { userId?: string }) {
  const { data } = useQuery({
    queryKey: ['user', userId],
    queryFn: () => fetchUser(userId!),
    enabled: !!userId, // Only run query if userId is truthy
  })
}

With Stale Time

function TodoList() {
  const { data } = useQuery({
    queryKey: ['todos'],
    queryFn: fetchTodos,
    staleTime: 1000 * 60 * 5, // Data stays fresh for 5 minutes
  })
}

Source

Implementation: useQuery.ts:50

Build docs developers (and LLMs) love