Capítulo 19 de 80

Chapter 19: Polling

Core Idea

refetchInterval refetches a query on a timer independent of staleTime, on a per-function basis when passed a function instead of a number (letting the query's own state decide whether/how fast to keep polling).

Key Concepts

  • Basic polling: refetchInterval: 5_000 refetches every 5s while there's at least one active observer, regardless of freshness — polling and staleness are independent mechanisms.
  • Adaptive interval: pass a function (query) => number | false — return false to stop polling (e.g. once a job's status is 'complete'), a number to keep going at that cadence; polling resumes automatically if the function would return a number again.
  • Background polling: paused by default when the tab loses focus, same as other refetch triggers; set refetchIntervalInBackground: true to keep polling in inactive tabs (dashboards, live data).
  • Deduplication scope: each component's useQuery runs its own timer (per-observer), but concurrent in-flight fetches for the same key are still deduplicated to one network request — timers are per-observer, network dedup is per-query.
  • Unreliable connectivity events: in environments where online/offline browser events don't fire (Electron, some WebViews), set networkMode: 'always' to skip the connectivity gate entirely for a polling query.

Code Examples

// Stop polling once a job finishes
useQuery({
  queryKey: ['job', jobId],
  queryFn: () => fetchJobStatus(jobId),
  refetchInterval: (query) => (query.state.data?.status === 'complete' ? false : 2_000),
})

// Keep polling even when the tab is in the background
useQuery({
  queryKey: ['portfolio'],
  queryFn: fetchPortfolio,
  refetchInterval: 30_000,
  refetchIntervalInBackground: true,
})
  • What it demonstrates: state-driven polling that self-terminates, and background-tab polling for dashboards.

Key Takeaways

  1. Prefer a function over a static number for refetchInterval whenever polling should stop on its own (job done, error state) — it's the built-in way to avoid a manual clearInterval dance.
  2. Remember polling timers are per-observer — two components polling the same key each run their own timer, even though simultaneous fetches still dedupe to one request.
  3. Set networkMode: 'always' for polling queries in non-browser or unreliable-connectivity-event environments (Electron, WebViews), not just React Native.

Connects To

  • Network Mode: networkMode: 'always' used here for unreliable connectivity detection.
  • Important Defaults: how refetchInterval relates to (and is independent of) staleTime.