Flutter Query

Flutter Query

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?> queryKey

Required

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) queryFn

Required

The function that fetches the data. Receives a QueryFunctionContext containing:

  • queryKey - The query key for this query
  • client - The QueryClient instance
  • signal - An AbortSignal for cancellation support
  • meta - Additional metadata from the query options

Must return a Future that resolves with data or throws an error.

enabled

bool? enabled

Default: 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? staleDuration

Default: StaleDuration.zero

How long until data is considered stale. Stale data is eligible for background refetching.

ValueDescription
StaleDuration(minutes: 5)Stale after 5 minutes
StaleDuration.zeroImmediately stale (default)
StaleDuration.infinityNever stale unless manually invalidated
StaleDuration.staticNever stale and ignores manual invalidation

See Data Staleness for more information.

gcDuration

GcDuration? gcDuration

Default: 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.

ValueDescription
GcDuration(minutes: 5)Garbage collected after 5 minutes (default)
GcDuration.zeroImmediately garbage collected when unused
GcDuration.infinityNever 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? placeholder

Placeholder 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? refetchOnMount

Default: RefetchOnMount.stale

Controls whether the query refetches when a widget mounts.

ValueDescription
RefetchOnMount.staleRefetch if data is stale (default)
RefetchOnMount.alwaysAlways refetch on mount
RefetchOnMount.neverNever refetch on mount

refetchOnResume

RefetchOnResume? refetchOnResume

Default: RefetchOnResume.stale

Controls whether the query refetches when the app resumes from the background.

ValueDescription
RefetchOnResume.staleRefetch if data is stale (default)
RefetchOnResume.alwaysAlways refetch on resume
RefetchOnResume.neverNever refetch on resume

refetchInterval

Duration? refetchInterval

If set, the query will continuously refetch at this interval.

useQuery(
  ['notifications'],
  (context) => fetchNotifications(),
  refetchInterval: Duration(seconds: 30),
);

retry

Duration? Function(int retryCount, TError error)? retry

Default: 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 null to stop retrying
  • Return a Duration to 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? retryOnMount

Default: true

If false, a query that previously failed will not retry when it mounts.

seed

TData? seed

Initial 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? seedUpdatedAt

The 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>? meta

Additional 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? queryClient

A 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 status

The overall status of the query.

ValueDescription
QueryStatus.pendingNo cached data and no fetch has completed
QueryStatus.successData is available
QueryStatus.errorThe most recent fetch failed

fetchStatus

FetchStatus fetchStatus

The current network status of the query.

ValueDescription
FetchStatus.fetchingThe query function is executing
FetchStatus.pausedThe query wants to fetch but is paused
FetchStatus.idleNo fetch is in progress

data

TData? data

The last successfully resolved data. Remains available even when a background refetch fails.

dataUpdatedAt

DateTime? dataUpdatedAt

The timestamp when data was last updated.

dataUpdateCount

int dataUpdateCount

The number of times data has been successfully fetched.

error

TError? error

The error from the most recent failed fetch, if any.

errorUpdatedAt

DateTime? errorUpdatedAt

The timestamp when error was last updated.

errorUpdateCount

int errorUpdateCount

The 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 failureCount

The number of consecutive failures. Increments on each failure, resets to 0 on every new fetch attempt.

failureReason

TError? failureReason

The error from the most recent failure. Resets to null on every new fetch attempt.

isEnabled

bool isEnabled

Whether the query is enabled. Equals to the enabled option passed to the hook.

isStale

bool isStale

Whether the data is considered stale based on staleDuration.

isFetchedAfterMount

bool isFetchedAfterMount

Whether the query has fetched since the widget mounted. Useful for avoiding display of previously cached data.

isPlaceholderData

bool isPlaceholderData

Whether the current data is placeholder data.

refetch

Future<QueryResult<TData, TError>> Function({
  bool cancelRefetch,
  bool throwOnError,
}) refetch

Manually trigger a refetch.

  • cancelRefetch - If true (default), cancels any in-flight fetch before starting a new one
  • throwOnError - If true, throws the error instead of returning it in the result

Derived getters

These properties derive from status and fetchStatus for convenience.

PropertyEquivalent
isPendingstatus == QueryStatus.pending
isSuccessstatus == QueryStatus.success
isErrorstatus == QueryStatus.error
isFetchingfetchStatus == FetchStatus.fetching
isPausedfetchStatus == FetchStatus.paused
isFetcheddataUpdateCount > 0 || errorUpdateCount > 0
isLoadingisPending && isFetching
isRefetchingisFetching && !isPending
isLoadingErrorisError && data == null
isRefetchErrorisError && data != null

On this page