The TanStack Query (formerly React Query) caching system is designed to efficiently manage server state, ensuring data consistency and minimal refetching. Hereβs an overview of its cache structure and key concepts:
At its core, the TanStack Query cache is organized around query keys. The cache holds metadata, the query result, and related information for each query key. The structure can be thought of as follows:
Cache
βββ Query Key 1 (Array or String)
βββ Query Data (Result from server)
βββ Metadata
β βββ Status (idle, loading, error, success)
β βββ Fetch Status (fetching, paused, stale, etc.)
β βββ Is Stale (true/false)
β βββ Updated At (timestamp)
β βββ Observer Count (active subscriptions)
β βββ Retry Attempts
β βββ Error (if any)
βββ Configuration
βββ Cache Time (ms)
βββ Stale Time (ms)
βββ Retry Config
βββ Other Options
Each query key serves as a unique identifier for a cached query, and the associated metadata and configuration define how it behaves.
'users'
) or nested arrays (['users', { page: 1 }]
) for complex queries.useQuery(['users', { page: 1 }], fetchUsers);
cacheTime
).status
: Indicates if the query is idle
, loading
, error
, or success
.fetchStatus
: Shows whether data is actively being fetched (fetching
, paused
, etc.).isStale
: Marks if the data is considered stale (based on staleTime
).useQuery
instances).retry
and retryDelay
options.status
, fetchStatus
, and updatedAt
timestamp.queryClient.invalidateQueries(queryKey)
.cacheTime
expires, it is removed from the cache.queryClient.setQueryData
, even before the server response.queryClient.setQueryData(['todos'], (old) => [...old, newTodo]);
TanStack Query provides configuration options to control caching behavior:
useQuery(['users'], fetchUsers, {
staleTime: 10000, // Data remains fresh for 10 seconds
cacheTime: 300000, // Cache persists for 5 minutes after inactive
refetchOnWindowFocus: false, // Disable refetching on window focus
retry: 3, // Retry up to 3 times on failure
retryDelay: (attempt) => Math.min(1000 * 2 ** attempt, 30000), // Exponential backoff
});
You can directly access or manipulate the cache using QueryClient
:
import { QueryClient } from '@tanstack/react-query';
const queryClient = new QueryClient();
// Access all cached queries
const allQueries = queryClient.getQueryCache().getAll();
// Get a specific query's cached data
const userData = queryClient.getQueryData(['users', { page: 1 }]);
// Manually set cached data
queryClient.setQueryData(['users', { page: 1 }], { name: 'John Doe' });
['users']
[ { id: 1, name: 'John' }, { id: 2, name: 'Jane' } ]
status: 'success'
fetchStatus: 'idle'
isStale: false
updatedAt: 1672519200000
queryClient.setQueryData(['users'], (old) => [...old, { id: 3, name: 'Alice' }]);