Master React Query caching to slash network overhead. Learn how to configure staleTime, gcTime, and background revalidation for a faster dashboard.
Previously in this course, we explored the Asynchronous Data Lifecycle, where we learned to handle loading, error, and success states manually. While that pattern is essential for understanding the basics, it doesn't scale well for complex applications. In this lesson, we shift to react query, a powerful library that abstracts away the manual labor of state synchronization, focusing specifically on how caching impacts performance and API overhead.
When you fetch data, you aren't just retrieving a value; you are creating a "snapshot" of the server state. The goal of caching is to determine how long that snapshot remains valid before you need to fetch a fresh one.
React Query manages this through two primary time-based configurations:
staleTime: This determines how long data is considered "fresh." If a component requests data that is still fresh, React Query returns the cached data immediately without making a network request.gcTime (formerly cacheTime): This defines how long inactive data stays in memory. Once a query becomes inactive (i.e., no components are using it), React Query keeps it in the cache for this duration before garbage collecting it.Think of staleTime as your performance threshold—it’s how long you are willing to trust the client-side state without verifying it against the server.
In our dashboard project, we frequently fetch user analytics. Fetching these on every component mount would be wasteful. Here is how we implement a caching strategy to optimize our API performance:
JAVASCRIPTimport { useQuery } from CE9178">'@tanstack/react-query'; const fetchDashboardStats = async () => { const res = await fetch(CE9178">'/api/dashboard-stats'); return res.json(); }; export const useDashboardStats = () => { return useQuery({ queryKey: [CE9178">'dashboard-stats'], queryFn: fetchDashboardStats, // Data remains fresh for 5 minutes, preventing redundant fetches staleTime: 1000 * 60 * 5, // Data stays in memory for 30 minutes after the component unmounts gcTime: 1000 * 60 * 30, // Disable automatic background revalidation on window focus refetchOnWindowFocus: false, }); };
By setting staleTime, we significantly reduce the number of unnecessary network requests. When the user navigates away from the dashboard and returns within five minutes, the data is pulled instantly from the cache.
Even when data is "stale," React Query doesn't necessarily show a loading spinner. By default, it performs background revalidation. If a user focuses the browser window or navigates back to a component, React Query will serve the stale data immediately while silently fetching the updated version in the background.
This is a massive UX win. The user sees content instantly, and the UI updates seamlessly if the data has changed. If you need to disable this behavior to save bandwidth, you can use refetchOnWindowFocus: false or refetchOnMount: false.
Modify your current dashboard data-fetching hook:
useDashboardStats or similar data-fetching hook.staleTime of 30 seconds.staleTime to 0 (default): This forces a network request on every mount. While it ensures the freshest data, it often creates a "loading flicker" that degrades the user experience.staleTime and gcTime: Remember, staleTime is about freshness, while gcTime is about memory management. If your gcTime is shorter than your staleTime, your cache will be deleted before it even has a chance to be "fresh." Always ensure gcTime is equal to or greater than staleTime.staleTime to Infinity for data that changes frequently. If the data is critical (like account balances), you need to balance performance with accuracy.Caching is the most effective lever you have for improving perceived performance. By fine-tuning staleTime and gcTime, you minimize redundant API traffic and ensure your dashboard remains snappy. React Query handles the heavy lifting, allowing you to focus on building features rather than managing loading states.
Up next: Mutations and Data Updates — we will learn how to push changes back to the server and keep the UI in sync.
Learn to implement protected routes in your React application. We'll show you how to guard dashboard pages and redirect unauthenticated users securely.
Read moreLearn how to use React Router to transform your dashboard into a seamless single-page application (SPA) with efficient routing and navigation.
Caching Strategies with React Query
Controlled vs Uncontrolled Components
Real-time Form Validation
Schema-based Validation with Zod
Handling Multi-step Forms
Optimizing Form Submissions
Performance Profiling with React DevTools
Refactoring for Scalability
Finalizing Dashboard Data Flow
Deploying the Application
Advanced Hook Composition
Implementing Middleware for State
Advanced Context Patterns
Router Loaders and Data Prefetching
Complex Route Guards
Handling Large Datasets in UI
Testing Hooks and Components
Managing Global Modals
Implementing Keyboard Shortcuts
Optimizing Asset Loading
Internationalization Basics
Managing WebSocket Connections