useQuery
Hook for fetching and caching asynchronous data
final QueryResult<TData, TError> result = useQuery<TData, TError>(
queryKey,
queryFn,
enabled: enabled,
staleDuration: staleDuration,
gcDuration: gcDuration,
placeholder: placeholder,
refetchOnMount: refetchOnMount,
refetchOnResume: refetchOnResume,
refetchInterval: refetchInterval,
retry: retry,
retryOnMount: retryOnMount,
seed: seed,
seedUpdatedAt: seedUpdatedAt,
meta: meta,
queryClient: queryClient,
);Parameters
queryKey
List<Object?> queryKeyRequired
The query key to use for this query. The key uniquely identifies the query in the cache. If two widgets use the same key, they share the same cache entry.
The query will automatically refetch when the key changes (unless enabled is
false).
See Query Keys for more information.
queryFn
Future<TData> Function(QueryFunctionContext context) queryFnRequired
The function that fetches the data. Receives a QueryFunctionContext
containing:
queryKey- The query key for this queryclient- TheQueryClientinstancesignal- AnAbortSignalfor cancellation supportmeta- Additional metadata from the query options
Must return a Future that resolves with data or throws an error.
enabled
bool? enabledDefault: true
Set to false to disable this query from automatically running. Use this for
dependent queries where you need to wait for other data before fetching.
staleDuration
StaleDuration? staleDurationDefault: StaleDuration.zero
How long until data is considered stale. Stale data is eligible for background refetching.
| Value | Description |
|---|---|
StaleDuration(minutes: 5) | Stale after 5 minutes |
StaleDuration.zero | Immediately stale (default) |
StaleDuration.infinity | Never stale unless manually invalidated |
StaleDuration.static | Never stale and ignores manual invalidation |
See Data Staleness for more information.
gcDuration
GcDuration? gcDurationDefault: GcDuration(minutes: 5)
How long unused cache data remains in memory before garbage collection. When a query has no active observers, its data will be garbage collected after this duration.
| Value | Description |
|---|---|
GcDuration(minutes: 5) | Garbage collected after 5 minutes (default) |
GcDuration.zero | Immediately garbage collected when unused |
GcDuration.infinity | Never garbage collected |
When multiple observers specify different gc durations for the same query, the longest duration is used.
See Garbage Collection for more information.
placeholder
TData? placeholderPlaceholder data to display while the query is pending. Unlike seed,
placeholder data is not persisted to the cache.
When placeholder data is active, result.isPlaceholderData is true.
refetchOnMount
RefetchOnMount? refetchOnMountDefault: RefetchOnMount.stale
Controls whether the query refetches when a widget mounts.
| Value | Description |
|---|---|
RefetchOnMount.stale | Refetch if data is stale (default) |
RefetchOnMount.always | Always refetch on mount |
RefetchOnMount.never | Never refetch on mount |
refetchOnResume
RefetchOnResume? refetchOnResumeDefault: RefetchOnResume.stale
Controls whether the query refetches when the app resumes from the background.
| Value | Description |
|---|---|
RefetchOnResume.stale | Refetch if data is stale (default) |
RefetchOnResume.always | Always refetch on resume |
RefetchOnResume.never | Never refetch on resume |
refetchInterval
Duration? refetchIntervalIf set, the query will continuously refetch at this interval.
useQuery(
['notifications'],
(context) => fetchNotifications(),
refetchInterval: Duration(seconds: 30),
);retry
Duration? Function(int retryCount, TError error)? retryDefault: 3 retries with exponential backoff (1s, 2s, 4s delays)
A callback that determines whether to retry a failed fetch and how long to wait.
The retryCount starts at 0 after the first failure and increments with each
retry attempt.
- Return
nullto stop retrying - Return a
Durationto retry after that delay
// Never retry
retry: (_, _) => null,
// Retry 3 times with fixed 3 seconds delay
retry: (retryCount, error) {
if (retryCount >= 3) return null;
return const Duration(seconds: 3);
}
// Retry only on network errors
retry: (retryCount, error) {
if (error is NetworkException) {
return Duration(seconds: 1);
}
return null;
}retryOnMount
bool? retryOnMountDefault: true
If false, a query that previously failed will not retry when it mounts.
seed
TData? seedInitial data to populate the cache. Unlike placeholder, seed data is persisted
to the cache and affects the query status.
A query with seed data starts in QueryStatus.success rather than
QueryStatus.pending.
seedUpdatedAt
DateTime? seedUpdatedAtThe timestamp when the seed data was last updated. Used to determine staleness
of seed data. Defaults to the current time if not specified.
meta
Map<String, dynamic>? metaAdditional metadata stored on the query. Accessible in the
QueryFunctionContext passed to queryFn.
useQuery(
['user', userId],
(context) {
final source = context.meta['source'];
return fetchUser(userId, source: source);
},
meta: {'source': 'profile_page'},
);queryClient
QueryClient? queryClientA custom QueryClient to use. If not provided, uses the client from the nearest
QueryClientProvider.
Returns
The hook returns a QueryResult<TData, TError> containing the status, data,
error, and helper methods.
status
QueryStatus statusThe overall status of the query.
| Value | Description |
|---|---|
QueryStatus.pending | No cached data and no fetch has completed |
QueryStatus.success | Data is available |
QueryStatus.error | The most recent fetch failed |
fetchStatus
FetchStatus fetchStatusThe current network status of the query.
| Value | Description |
|---|---|
FetchStatus.fetching | The query function is executing |
FetchStatus.paused | The query wants to fetch but is paused |
FetchStatus.idle | No fetch is in progress |
data
TData? dataThe last successfully resolved data. Remains available even when a background refetch fails.
dataUpdatedAt
DateTime? dataUpdatedAtThe timestamp when data was last updated.
dataUpdateCount
int dataUpdateCountThe number of times data has been successfully fetched.
error
TError? errorThe error from the most recent failed fetch, if any.
errorUpdatedAt
DateTime? errorUpdatedAtThe timestamp when error was last updated.
errorUpdateCount
int errorUpdateCountThe total number of times the query has entered the error state. Only increments after all retries are exhausted, not on each failed retry attempt.
failureCount
int failureCountThe number of consecutive failures. Increments on each failure, resets to 0 on every new fetch attempt.
failureReason
TError? failureReasonThe error from the most recent failure. Resets to null on every new fetch
attempt.
isEnabled
bool isEnabledWhether the query is enabled. Equals to the enabled option passed to the hook.
isStale
bool isStaleWhether the data is considered stale based on staleDuration.
isFetchedAfterMount
bool isFetchedAfterMountWhether the query has fetched since the widget mounted. Useful for avoiding display of previously cached data.
isPlaceholderData
bool isPlaceholderDataWhether the current data is placeholder data.
refetch
Future<QueryResult<TData, TError>> Function({
bool cancelRefetch,
bool throwOnError,
}) refetchManually trigger a refetch.
cancelRefetch- Iftrue(default), cancels any in-flight fetch before starting a new onethrowOnError- Iftrue, throws the error instead of returning it in the result
Derived getters
These properties derive from status and fetchStatus for convenience.
| Property | Equivalent |
|---|---|
isPending | status == QueryStatus.pending |
isSuccess | status == QueryStatus.success |
isError | status == QueryStatus.error |
isFetching | fetchStatus == FetchStatus.fetching |
isPaused | fetchStatus == FetchStatus.paused |
isFetched | dataUpdateCount > 0 || errorUpdateCount > 0 |
isLoading | isPending && isFetching |
isRefetching | isFetching && !isPending |
isLoadingError | isError && data == null |
isRefetchError | isError && data != null |