type
QueryOptions
export type QueryOptions<TData, TSelected = TData> = {|
readonly queryKey: QueryKey,
readonly queryFn: (context: FetchContext<TData>) => Promise<TData>,
/** `false` means "do not fetch this yet"; a manual refetch still works. */
readonly enabled?: boolean,
/** How long an answer counts as fresh. `Infinity` means "until I say so". */
readonly staleTime?: number,
/** How long an unwatched entry is kept before it is collected. */
readonly gcTime?: number,
readonly retry?: RetryPolicy,
readonly retryDelay?: RetryDelay,
/** Narrow the data. See the module docs for what it buys. */
readonly select?: (data: TData) => TSelected,
/** Shown while there is nothing yet; never written to the cache. */
readonly placeholderData?: mixed | ((previous: TData | void) => mixed),
readonly refetchInterval?: number | null,
readonly refetchOnWindowFocus?: boolean,
readonly refetchOnReconnect?: boolean,
|};
How a component asks for a key.
Everything except the key and the function has a default on the client, so an application sets staleTime once instead of at every call site.
type
ResolvedQueryOptions
export type ResolvedQueryOptions<TData, TSelected = TData> = {|
readonly queryKey: QueryKey,
readonly queryFn: (context: FetchContext<TData>) => Promise<TData>,
readonly enabled: boolean,
readonly staleTime: number,
readonly gcTime: number,
readonly retry: RetryPolicy,
readonly retryDelay: RetryDelay,
readonly select?: (data: TData) => TSelected,
readonly placeholderData?: mixed | ((previous: TData | void) => mixed),
readonly refetchInterval: number | null,
readonly refetchOnWindowFocus: boolean,
readonly refetchOnReconnect: boolean,
|};
The same options with the client's defaults filled in.
type
QueryResult
export type QueryResult<T> = {|
readonly data: T | void,
readonly error: Error | null,
readonly status: QueryStatus,
readonly fetchStatus: FetchStatus,
/** There is no answer yet, not even a failed one. */
readonly isPending: boolean,
/** The first load: pending *and* a request is in flight. */
readonly isLoading: boolean,
readonly isSuccess: boolean,
readonly isError: boolean,
/** A request is in flight, first load or refresh. */
readonly isFetching: boolean,
/** A request is in flight over data that is already on screen. */
readonly isRefetching: boolean,
readonly isStale: boolean,
readonly isPlaceholderData: boolean,
/** Failed attempts in the request in flight, for "retrying (2 of 3)". */
readonly failureCount: number,
/** Refetch now, superseding anything in flight. Never rejects. */
readonly refetch: () => Promise<void>,
|};
What a component sees.
Deliberately without timestamps. A clock reading in a render-visible snapshot re-renders every observer on every successful refresh, even when the answer is identical — which is exactly what structural sharing exists to prevent, and it also defeats select: narrowing to user.name is only worth having if the snapshot is insensitive to the fields it discarded, and a dataUpdatedAt beside it moves whenever *any* field does.
So the snapshot carries decisions rather than readings. isStale is the one the clock reaches, because it is the one a component can act on. client.getQueryState(key) has dataUpdatedAt, checkedAt and the rest for a devtool or a "last updated" label that wants them.