Overview
The QueryObserver class is used to subscribe to a query and receive reactive updates when the query’s state changes. It’s the foundation for framework-specific hooks like useQuery in React.
Constructor
const observer = new QueryObserver < TQueryFnData , TError , TData , TQueryData , TQueryKey >(
client : QueryClient ,
options : QueryObserverOptions < TQueryFnData , TError , TData , TQueryData , TQueryKey >
)
options
QueryObserverOptions
required
Options for the query observer queryFn
QueryFunction<TQueryFnData, TQueryKey>
Function that the query will use to fetch data
enabled
boolean | ((query: Query) => boolean)
Enable or disable the query. Defaults to true.
staleTime
number | 'static' | ((query: Query) => number | 'static')
Time in milliseconds after which data is considered stale
Time in milliseconds that unused cache data remains in memory
refetchOnMount
boolean | 'always' | ((query: Query) => boolean | 'always')
Refetch on mount if data is stale. Defaults to true.
refetchOnWindowFocus
boolean | 'always' | ((query: Query) => boolean | 'always')
Refetch on window focus if data is stale. Defaults to true.
refetchOnReconnect
boolean | 'always' | ((query: Query) => boolean | 'always')
Refetch on reconnect if data is stale. Defaults to true.
refetchInterval
number | false | ((query: Query) => number | false)
Continuously refetch at this interval in milliseconds
refetchIntervalInBackground
Continue refetching when window is in background. Defaults to false.
select
(data: TQueryData) => TData
Transform or select a part of the data
placeholderData
TQueryData | PlaceholderDataFunction<TQueryData>
Placeholder data to show while loading
notifyOnChangeProps
Array<keyof QueryObserverResult> | 'all' | (() => Array<keyof QueryObserverResult> | 'all')
Which properties trigger re-renders
Example:
const observer = new QueryObserver ( queryClient , {
queryKey: [ 'todos' ],
queryFn: fetchTodos ,
staleTime: 5000 ,
})
Methods
subscribe()
Subscribes to query updates.
const unsubscribe = observer . subscribe (
listener : ( result : QueryObserverResult < TData , TError >) => void
): () => void
listener
(result: QueryObserverResult<TData, TError>) => void
required
Callback function that receives query results
Returns: Function to unsubscribe
Example:
const unsubscribe = observer . subscribe (( result ) => {
console . log ( 'Data:' , result . data )
console . log ( 'Status:' , result . status )
console . log ( 'Is loading:' , result . isLoading )
})
// Later, unsubscribe
unsubscribe ()
getCurrentResult()
Returns the current result without subscribing.
const result = observer . getCurrentResult (): QueryObserverResult < TData , TError >
Returns: Current query result
The error object if query failed
status
'pending' | 'error' | 'success'
The status of the query
fetchStatus
'fetching' | 'paused' | 'idle'
The fetch status of the query
Is true whenever the first fetch is in-flight
Is true when there’s no cached data and no query attempt has finished
Is true when the query has successfully fetched data
Is true when the query has encountered an error
Is true whenever the query function is executing
Is true when a background refetch is in-flight
Is true if the data is stale
Timestamp of when data was last updated
Timestamp of when error was last updated
refetch
(options?: RefetchOptions) => Promise<QueryObserverResult>
Function to manually refetch the query
setOptions()
Updates the observer’s options.
observer . setOptions (
options : QueryObserverOptions < TQueryFnData , TError , TData , TQueryData , TQueryKey >
): void
options
QueryObserverOptions
required
New options for the observer
Example:
observer . setOptions ({
queryKey: [ 'todos' ],
queryFn: fetchTodos ,
staleTime: 10000 , // Updated stale time
})
getOptimisticResult()
Returns an optimistic result based on the provided options, without triggering a fetch.
const result = observer . getOptimisticResult (
options : DefaultedQueryObserverOptions < TQueryFnData , TError , TData , TQueryData , TQueryKey >
): QueryObserverResult < TData , TError >
Returns: Optimistic query result
This method is useful for framework integrations that need to compute what the result would be before actually subscribing.
refetch()
Manually refetches the query.
const result = await observer . refetch ( options ?: RefetchOptions ): Promise < QueryObserverResult < TData , TError >>
Cancel currently running query before refetching. Defaults to true.
Throw error instead of returning it in result. Defaults to false.
Returns: Promise resolving to the query result
Example:
const result = await observer . refetch ()
console . log ( 'Refetched data:' , result . data )
fetchOptimistic()
Fetches a query with new options without subscribing.
const result = await observer . fetchOptimistic (
options : QueryObserverOptions < TQueryFnData , TError , TData , TQueryData , TQueryKey >
): Promise < QueryObserverResult < TData , TError >>
Returns: Promise resolving to the query result
getCurrentQuery()
Returns the underlying Query instance.
const query = observer . getCurrentQuery (): Query < TQueryFnData , TError , TQueryData , TQueryKey >
Returns: The Query instance
trackResult()
Returns a proxied result that tracks which properties are accessed.
const trackedResult = observer . trackResult (
result : QueryObserverResult < TData , TError > ,
onPropTracked ?: ( key : keyof QueryObserverResult ) => void
): QueryObserverResult < TData , TError >
This is used internally for optimizing re-renders by only triggering updates when tracked properties change.
destroy()
Destroys the observer and unsubscribes from the query.
Example:
Properties
options
The current options for the observer.
observer . options : QueryObserverOptions < TQueryFnData , TError , TData , TQueryData , TQueryKey >
Type Parameters
TQueryFnData - The type of data returned by the query function
TError - The type of error that can be thrown (defaults to DefaultError)
TData - The type of data after selection/transformation
TQueryData - The type of data stored in the cache
TQueryKey - The type of the query key
Usage Example
import { QueryClient , QueryObserver } from '@tanstack/query-core'
const queryClient = new QueryClient ()
const observer = new QueryObserver ( queryClient , {
queryKey: [ 'todos' ],
queryFn : async () => {
const response = await fetch ( '/api/todos' )
return response . json ()
},
staleTime: 5000 ,
})
// Subscribe to updates
const unsubscribe = observer . subscribe (( result ) => {
if ( result . isLoading ) {
console . log ( 'Loading...' )
} else if ( result . isError ) {
console . error ( 'Error:' , result . error )
} else if ( result . isSuccess ) {
console . log ( 'Data:' , result . data )
}
})
// Later, clean up
unsubscribe ()
observer . destroy ()