TanStack Query for Server State

Fetch, cache, mutate and refetch server data with TanStack Query in a React Native app.

TanStack Query manages the lifecycle of server data: fetch, cache, retry, refresh and invalidate.

Core concepts

  1. useQuery: Describe data with a queryKey and a queryFn. You get loading, error and data states plus caching and background refresh. — TanStack Query
  2. useMutation: Wrap writes in mutations and invalidate or update related queries on success. Use optimistic updates with rollback for snappy UIs. — TanStack Query
  3. Query keys: Keys identify cached data. Use arrays like ['items', filters] so changing filters fetches separately and caching works. — TanStack Query
  4. React Native wiring: Hook onlineManager to NetInfo and focusManager to AppState so queries pause offline and refetch when the app returns to the foreground. — TanStack Query React Native
  5. Offline persistence: Persist the query cache to storage for instant startup and offline reading, with a sensible maxAge and a cache-busting key on schema changes. — TanStack Query persist

Concept videos

YouTube channels and searches for these topics. On a large screen they open in the reading panel next to the roadmap.

Explanation

Stale time

Data is stale immediately by default. Set staleTime per query to control how often it refetches, balancing freshness against battery and data use.

Error and retry policy

Default retries are fine for transient network errors, but disable them for 4xx errors so users do not wait on requests that cannot succeed.

What Is It?

TanStack Query is an async state manager that caches and synchronises data from servers.

Why Should I Care?

It replaces hand-written loading flags and effect-based fetching that agents often get subtly wrong.

Real World Analogy

It is a courier who keeps a local copy of remote files, knows when a copy is stale, and re-fetches without bothering you.

Visual Mental Model

text
queryKey -> cache hit? fresh -> return; stale -> return + refetch -> update subscribers

Smallest Possible Example

ts
import { useQuery } from '@tanstack/react-query';

export function useItems(filter: string) {
  return useQuery({
    queryKey: ['items', filter],
    queryFn: () => fetch(`/api/items?filter=${filter}`).then((r) => r.json()),
    staleTime: 60_000,
  });
}

Common Mistakes

❌ Using useEffect and useState to fetch.

You lose caching, deduping and retries, and create race conditions.

❌ Query keys that omit variables.

Different filters share one cache entry and show wrong data.

Build This Mini Project

Build a list with filters via useQuery, a create form with an optimistic useMutation, and a pull-to-refresh that calls refetch.

Prompts for Cursor, Claude Code & Codex

Paste these into Cursor, Claude Code, Codex, or any coding agent. Replace the bracketed parts with your app details, and keep the agent in plan mode first so you review the approach before it edits files.

Convert effect fetching

text
Find components that fetch data with useEffect and useState. Convert them to TanStack Query hooks in hooks/ with proper query keys, loading and error UI, and invalidate after mutations.

Rules, databases & blogs to use

Resources

Threads in the same domain as this chapter — go deeper on iHateReading without leaving the roadmap.

How to build an AI chat app with Vercel AI SDK and Firebase cover

How to build an AI chat app with Vercel AI SDK and Firebase

Chat UI, streaming and backend wiring for an AI feature.

Agent harnessing: the part of building AI agents nobody talks about cover

Agent harnessing: the part of building AI agents nobody talks about

Loop, tools, memory, sandbox, and tracing live in your code — not the model weights.