Back
Web Fundamentals

React Query (TanStack Query): Server State Caching

Web Fundamentals
Build & Deployment: Monorepo, CI/CD, Strategies & Release SafetyState Management: Choosing the Right SolutionRedux: Predictable State Container (RTK + RTK Query)React Query (TanStack Query): Server State CachingData Fetching Patterns: REST, GraphQL, tRPC & Real-timeGraphQL Fundamentals for Frontend: Shape, Caching, and TradeoffsgRPC-Web Fundamentals: Browser Constraints and Proxy ModelCaching Strategies: Client, Server & EdgeData Normalization: Organizing State for PerformanceAPI Design Best Practices: Pagination, Errors, Versioning & Type SafetyAPI Versioning Strategies for Frontend CompatibilityPagination: Offset vs Cursor-BasedRate Limiting & API Resilience: Retries, Backoff, Jitter, IdempotencyHow Frontend Developers Can Handle Millions of API Requests Without Crashing EverythingBrowser Storage: Cookies, SessionStorage, LocalStorage, IndexedDBReal-time Communication: WebSockets, SSE & PollingWebRTC: Real-Time Communication in the BrowserCore Web Vitals: LCP, INP & CLSPerformance Optimization Trade-offsCritical Resource Prioritization: Optimize Loading OrderCode Splitting: Optimize Bundle Size with Dynamic ImportsTree Shaking: Eliminate Dead Code from Your BundleLazy Loading: Load Resources On-DemandResource Hints: Preload, Prefetch & PreconnectText Compression: Gzip and BrotliImage & Video Optimization: Modern Formats & TechniquesAdaptive Loading: Optimize for Device & NetworkList Virtualization: Render Large Lists EfficientlyWeb Workers vs Main Thread: Offloading Heavy WorkMemory Leaks in Frontend Apps: Detection & PreventionManaging Third-Party Scripts: Optimization StrategiesHow CDNs Work: Edge Delivery, Caching & PerformanceHTTP Caching Deep Dive: Cache-Control, ETag & RevalidationService Workers & Offline Strategy: Cache First, Network First & Update LifecyclePWA Fundamentals: Manifest, Installability & Offline UXCritical Rendering PathScript Loading: async vs deferEvent Loop: Understanding JavaScript Execution ModelJavaScript Module Systems: CJS vs ESM vs UMDDynamic Module Loading: import() FunctionImport on Interaction: Load When User InteractsImport on Visibility: Lazy Loading with IntersectionObserverBrowser Rendering Pipeline & Layout ThrashingRendering Strategies: CSR vs SSR vs SSG vs ISRStreaming SSR: Progressive HTML StreamingIslands Architecture: Independent Component HydrationReact Server Components: Zero-JS Server RenderingFramework Reactivity: React, Vue, Svelte & SolidHTTP/1.1 vs HTTP/2 vs HTTP/3 (QUIC) for Frontend PerformanceDNS Resolution: Path, TTL, Caching & Frontend ImpactCross-Site Scripting (XSS) AttacksCross-Site Request Forgery (CSRF) AttacksCORS Explained: Cross-Origin Resource SharingCORS Preflight in Practice: Credentials, Simple Requests & MisconfigurationsContent Security Policy (CSP)Why is HTTPS Secure? Understanding TLS/SSLAuthorization Best PracticesCookie Security & Session Hardening: SameSite, HttpOnly, Secure
mediumFrontend Architecture

React Query (TanStack Query): Server State Caching

TL;DRReact Query owns server state. Use query keys, staleTime, invalidation, and optimistic updates for fast + correct UI.
Very High Signal
Google
Meta
Netflix
Agoda
30-Second Answerstart every interview with this

React Query (TanStack Query) is the standard solution for managing server state in React apps. It handles caching, request deduplication, background refetching, mutations, and optimistic updates with minimal boilerplate.

You tell it what data you want (query key). It fetches, caches, and keeps it fresh automatically. When you change data (mutation), it knows what to update or invalidate. You focus on UI; it handles the messy parts of server synchronization.

Define queryKey + queryFn
React Query handles fetching + caching
UI subscribes via useQuery
Mutations trigger smart invalidation/updates

1Query Keys & Basic Usage

Query keys are the identity of your cached data. Use stable, hierarchical arrays. React Query automatically dedupes and caches based on these keys.

useUser.tsts
const { data, isLoading } = useQuery({
  queryKey: ['user', userId],
  queryFn: () => fetchUser(userId),
  staleTime: 60_000
});

2Caching Strategy (staleTime, gcTime)

staleTime controls how long data is considered fresh. gcTime controls how long inactive queries stay in memory.

3Mutations & Optimistic Updates

Use useMutation with invalidateQueries for correctness or setQueryData for instant UI. Optimistic updates provide rollback on error.

4Pagination & Infinite Scroll

Keep pagination params in query keys. Use useInfiniteQuery for infinite scrolling with getNextPageParam.

PropertyReact QueryManual Fetching
Best ForServer/API dataSimple cases
FeaturesCaching, deduping, background refetch, mutationsNone built-in
ComplexityLowHigh (you build everything)

React Query

Best For

Server/API data

Features

Caching, deduping, background refetch, mutations

Complexity

Low

Manual Fetching

Best For

Simple cases

Features

None built-in

Complexity

High (you build everything)

Common questions

  • ›“What is React Query and why use it?”
  • ›“Explain staleTime vs gcTime.”
  • ›“How do you handle optimistic updates?”
  • ›“When would you use React Query vs Redux/Zustand?”

What interviewers look for

  • Clear separation of server vs client state
  • Understanding of query keys and invalidation
  • Knowledge of optimistic updates with rollback
  • Modern best practice (React Query for server state)

Short answer (60 sec)

React Query manages server state with automatic caching, deduplication, background refetching, and mutations. Use stable query keys, staleTime for freshness control, and invalidateQueries after mutations.

Detailed answer (senior level)

React Query owns server state. Use hierarchical query keys for cache identity. staleTime controls refetch frequency, gcTime controls memory cleanup. Mutations use invalidateQueries for correctness or setQueryData for instant UI. Optimistic updates provide rollback on error. This approach eliminates most manual loading/error state management and keeps UI fast and correct.

  • Using unstable query keys (inline objects)
  • Storing server data in Zustand/Redux instead of React Query
  • Forgetting to invalidate after mutations
  • Not using keepPreviousData in pagination
  • Overusing staleTime: 0 (too many requests)
Key Takeaways
  • ✓React Query is the standard for server state management
  • ✓Query keys are the foundation of caching and invalidation
  • ✓Use staleTime to control freshness, gcTime for memory
  • ✓invalidateQueries for correctness, setQueryData for instant UX
  • ✓Optimistic updates need proper rollback
  • ✓Separate server state (React Query) from client state (Zustand/Context)
  • ✓Always measure and tune based on real usage patterns
Previous TopicRedux: Predictable State Container (RTK + RTK Query)Next Topic Data Fetching Patterns: REST, GraphQL, tRPC & Real-time

On this page