Capítulo 17 de 80

Chapter 17: Background Fetching Indicators

Core Idea

status === 'pending' is only the right signal for the initial hard-loading state; a background refetch of already-loaded data should be surfaced via the separate isFetching boolean instead, either per-query or globally via useIsFetching().

Key Concepts

  • Per-query indicator: isFetching is true any time the queryFn is running, independent of status — use it to show a subtle "Refreshing…" indicator without replacing the existing content with a full loading state.
  • Global indicator: useIsFetching() (no arguments) reports whether any query anywhere in the app is currently fetching, useful for a single top-level activity indicator instead of one per component.

Code Examples

function Todos() {
  const { status, data: todos, error, isFetching } = useQuery({
    queryKey: ['todos'],
    queryFn: fetchTodos,
  })

  if (status === 'pending') return <span>Loading...</span>
  if (status === 'error') return <span>Error: {error.message}</span>
  return (
    <>
      {isFetching ? <div>Refreshing...</div> : null}
      <div>{todos.map((todo) => <Todo key={todo.id} todo={todo} />)}</div>
    </>
  )
}

// App-wide indicator
function GlobalLoadingIndicator() {
  const isFetching = useIsFetching()
  return isFetching ? <div>Queries are fetching in the background...</div> : null
}
  • What it demonstrates: isFetching layered on top of the hard status === 'pending' gate for a subtle background-refresh indicator, plus useIsFetching() for one indicator covering the whole app.

Key Takeaways

  1. Use status/isPending for the initial full-page/component loading state, and isFetching for everything after — conflating them makes background refetches look like full reloads.
  2. useIsFetching() needs no arguments to aggregate every active query in the tree — reach for query-key filters only when you need to scope it.

Connects To

  • Queries: the status/fetchStatus model isFetching is derived from.
  • useIsFetching: full reference for the hook used here, including its optional filters.