Query
The Query class represents a single query instance in the cache. It manages the lifecycle of a query, including fetching, caching, and state management.
Import
import { Query } from '@tanstack/query-core'
Constructor
class Query<
TQueryFnData = unknown,
TError = DefaultError,
TData = TQueryFnData,
TQueryKey extends QueryKey = QueryKey,
> {
constructor(config: QueryConfig<TQueryFnData, TError, TData, TQueryKey>)
}
Type Parameters
The type of data returned by the query function
TError
type
default:"DefaultError"
The type of error that can be thrown
TData
type
default:"TQueryFnData"
The type of data after transformation
The type of the query key
Properties
state
state: QueryState<TData, TError>
The current state of the query.
interface QueryState<TData = unknown, TError = DefaultError> {
data: TData | undefined
dataUpdateCount: number
dataUpdatedAt: number
error: TError | null
errorUpdateCount: number
errorUpdatedAt: number
fetchFailureCount: number
fetchFailureReason: TError | null
fetchMeta: FetchMeta | null
isInvalidated: boolean
status: 'pending' | 'error' | 'success'
fetchStatus: 'fetching' | 'paused' | 'idle'
}
queryKey
The unique key for this query.
queryHash
A hashed version of the query key used for internal lookups.
options
options: QueryOptions<TQueryFnData, TError, TData, TQueryKey>
The query configuration options.
Methods
fetch
fetch(
options?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>,
fetchOptions?: FetchOptions
): Promise<TData>
Fetch or refetch the query data.
cancel
cancel(options?: CancelOptions): Promise<void>
Cancel any ongoing query fetches.
invalidate
Mark the query as stale/invalidated.
setState
setState(
state: QueryState<TData, TError>,
options?: SetStateOptions
): void
Update the query state.
setData
setData(
updater: Updater<TData | undefined, TData | undefined>,
options?: SetDataOptions
): TData | undefined
Manually set the query data.
isStale
Check if the query is stale based on staleTime.
isStaleByTime
isStaleByTime(staleTime?: number): boolean
Check if the query is stale based on a specific stale time.
destroy
Clean up and remove the query.
Examples
Accessing Query State
import { QueryClient } from '@tanstack/query-core'
const queryClient = new QueryClient()
const queryCache = queryClient.getQueryCache()
// Get a specific query
const query = queryCache.find({ queryKey: ['posts'] })
if (query) {
console.log('Query Key:', query.queryKey)
console.log('Query Hash:', query.queryHash)
console.log('Status:', query.state.status)
console.log('Data:', query.state.data)
console.log('Error:', query.state.error)
console.log('Fetch Status:', query.state.fetchStatus)
console.log('Is Stale:', query.isStale())
}
Finding Queries
import { QueryClient } from '@tanstack/query-core'
const queryClient = new QueryClient()
const queryCache = queryClient.getQueryCache()
// Get all queries
const allQueries = queryCache.getAll()
// Find queries by partial key
const postQueries = queryCache.findAll({ queryKey: ['posts'] })
// Find with predicate
const staleQueries = queryCache.findAll({
predicate: (query) => query.isStale(),
})
console.log(`Total queries: ${allQueries.length}`)
console.log(`Post queries: ${postQueries.length}`)
console.log(`Stale queries: ${staleQueries.length}`)
Manually Invalidating Queries
import { QueryClient } from '@tanstack/query-core'
const queryClient = new QueryClient()
const query = queryClient.getQueryCache().find({ queryKey: ['posts'] })
if (query) {
// Mark as stale
query.invalidate()
// Refetch if there are active observers
query.fetch()
}
Setting Query Data Manually
import { QueryClient } from '@tanstack/query-core'
const queryClient = new QueryClient()
const query = queryClient.getQueryCache().find({ queryKey: ['post', 1] })
if (query) {
// Set data directly
query.setData({ id: 1, title: 'Updated Title' })
// Or use an updater function
query.setData((oldData) => ({
...oldData,
title: 'Updated Title',
}))
}
Checking Query Staleness
import { QueryClient } from '@tanstack/query-core'
const queryClient = new QueryClient()
const query = queryClient.getQueryCache().find({ queryKey: ['posts'] })
if (query) {
// Check with default staleTime
const isStale = query.isStale()
// Check with custom staleTime (5 minutes)
const isStaleByTime = query.isStaleByTime(5 * 60 * 1000)
console.log('Is stale (default):', isStale)
console.log('Is stale (5 min):', isStaleByTime)
}
Subscribing to Query Changes
import { QueryClient } from '@tanstack/query-core'
const queryClient = new QueryClient()
const queryCache = queryClient.getQueryCache()
// Subscribe to all query changes
const unsubscribe = queryCache.subscribe((event) => {
console.log('Event type:', event.type)
console.log('Query:', event.query.queryKey)
console.log('Status:', event.query.state.status)
})
// Clean up
unsubscribe()
Canceling Queries
import { QueryClient } from '@tanstack/query-core'
const queryClient = new QueryClient()
// Cancel all queries
await queryClient.cancelQueries()
// Cancel specific queries
await queryClient.cancelQueries({ queryKey: ['posts'] })
// Or cancel directly on the query
const query = queryClient.getQueryCache().find({ queryKey: ['posts'] })
if (query) {
await query.cancel()
}
Removing Queries
import { QueryClient } from '@tanstack/query-core'
const queryClient = new QueryClient()
const query = queryClient.getQueryCache().find({ queryKey: ['posts'] })
if (query) {
// Remove the query from cache
query.destroy()
// Or use queryClient methods
queryClient.removeQueries({ queryKey: ['posts'] })
}
import { QueryClient } from '@tanstack/query-core'
const queryClient = new QueryClient()
const query = queryClient.getQueryCache().find({ queryKey: ['posts'] })
if (query) {
console.log('Data Update Count:', query.state.dataUpdateCount)
console.log('Data Updated At:', new Date(query.state.dataUpdatedAt))
console.log('Error Update Count:', query.state.errorUpdateCount)
console.log('Fetch Failure Count:', query.state.fetchFailureCount)
console.log('Is Invalidated:', query.state.isInvalidated)
}
Fetching with Options
import { QueryClient } from '@tanstack/query-core'
const queryClient = new QueryClient()
const query = queryClient.getQueryCache().find({ queryKey: ['posts'] })
if (query) {
// Fetch with custom options
await query.fetch({
queryFn: () => fetchPosts(),
staleTime: 60 * 1000,
gcTime: 5 * 60 * 1000,
})
// Fetch with meta information
await query.fetch(undefined, {
cancelRefetch: true,
meta: { requestId: '123' },
})
}
Query State
The query state object contains:
status
'pending' | 'error' | 'success'
The current status of the query
fetchStatus
'fetching' | 'paused' | 'idle'
The fetch status of the query
The data returned by the query function
The error thrown by the query function (only set on error)
The number of times the data has been updated
Timestamp when data was last updated
The number of times the query has errored
Timestamp when error was last updated
The number of consecutive fetch failures
The reason for the last fetch failure
Whether the query has been invalidated
Additional metadata about the fetch
Notes
Query is a low-level class typically created and managed by QueryCache
- Each unique query key gets its own
Query instance
- Queries are kept in cache based on
gcTime (garbage collection time)
- The
queryHash is used for efficient internal lookups
- Queries support multiple concurrent observers (e.g., multiple components using the same query)
- State changes trigger notifications to observers and cache subscribers
- Queries automatically refetch based on staleTime and other configuration
- The
fetch() method is used internally by observers to trigger data fetching
- Use
QueryClient methods instead of directly manipulating queries in most cases