DEV Community

Hamza Khan
Hamza Khan

Posted on

πŸ› οΈ Optimizing React Apps with SWR and React Query: A Technical Deep Dive πŸš€

React applications thrive on data, but inefficient data fetching can turn an otherwise smooth app into a sluggish experience. Enter SWR (stale-while-revalidate) and React Query, two powerful libraries designed to manage server state efficiently, reduce boilerplate, and optimize your app’s performance.

In this post, we’ll compare SWR and React Query, explore their core concepts, and demonstrate how to use them with examples.

Why Do We Need SWR or React Query?

Fetching and managing server-side data in React traditionally involves:

  • Calling APIs using fetch or axios.
  • Managing loading, error, and success states manually.
  • Caching, revalidating, and synchronizing data with the server.

This approach can lead to:

  • Bloated codebases with repetitive logic.
  • Outdated or stale data being rendered.
  • Inefficient network calls, degrading user experience.

SWR and React Query handle these concerns out of the box, making them essential for modern React apps.

SWR: Stale-While-Revalidate

Core Concept

SWR fetches data once and keeps it cached while enabling revalidation in the background. This ensures UI responsiveness with fresh data being fetched seamlessly.

Installation

npm install swr
Enter fullscreen mode Exit fullscreen mode

Basic Example with SWR

import useSWR from 'swr';

// Fetcher function
const fetcher = (url) => fetch(url).then((res) => res.json());

function App() {
  const { data, error, isLoading } = useSWR('/api/data', fetcher);

  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <div>
      <h1>Data:</h1>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Key Features of SWR

  • Automatic Caching: Cached data is reused for subsequent renders.
  • Stale Data Rendering: Provides old data while fetching fresh data in the background.
  • Focus Revalidation: Re-fetches data when the tab regains focus.
  • Interval Revalidation: Supports periodic data fetching.

React Query: The TanStack Star

Core Concept

React Query focuses on managing server-state with powerful tools for caching, data synchronization, and state management.

Installation

npm install @tanstack/react-query
Enter fullscreen mode Exit fullscreen mode

Basic Example with React Query

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

// Fetcher function
const fetchData = async () => {
  const res = await fetch('/api/data');
  if (!res.ok) throw new Error('Network response was not ok');
  return res.json();
};

function App() {
  const { data, error, isLoading } = useQuery(['data'], fetchData);

  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <div>
      <h1>Data:</h1>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Key Features of React Query

  • Fine-Grained Cache Management: Control cache duration and behavior.
  • Mutations: Handles server-side data updates seamlessly.
  • Infinite Queries: Ideal for paginated or infinite scrolling data.
  • Prefetching: Fetch data in advance for smoother navigation.

Performance Comparison

Feature SWR React Query
Cache Mechanism Lightweight key-based cache Advanced, customizable cache
Mutations Limited Powerful with built-in APIs
Pagination/Infinite Manual implementation Built-in support
Developer Experience Minimal setup, easy to use More features, steeper learning curve
Community Support Active Very active

Choosing the Right Tool

  • Use SWR for simple use cases like fetching and caching data with minimal configuration.
  • Use React Query for complex use cases requiring advanced cache control, mutations, or infinite queries.

Which one would you choose for your next project? Why?

Combining with React Suspense

Both libraries can integrate seamlessly with React’s Suspense API for even better user experiences:

const fetcher = (url) => fetch(url).then((res) => res.json());

function DataComponent() {
  const { data } = useSWR('/api/data', fetcher, { suspense: true });

  return <pre>{JSON.stringify(data, null, 2)}</pre>;
}

function App() {
  return (
    <React.Suspense fallback={<p>Loading...</p>}>
      <DataComponent />
    </React.Suspense>
  );
}
Enter fullscreen mode Exit fullscreen mode

Best Practices for Optimized Data Fetching

  1. Choose the Right Cache Strategy: Use SWR for simplicity and React Query for customization.
  2. Optimize API Endpoints: Combine queries to minimize network calls.
  3. Leverage Prefetching: Use React Query’s prefetch APIs to preload data.
  4. Use React Suspense: Improve perceived performance with fallback UIs.

Conclusion

SWR and React Query are game changers for managing server-state in React apps. Whether you're building a dashboard, an e-commerce app, or a real-time chat, these tools can significantly enhance performance and developer experience.

Are you using SWR, React Query, or both in your projects? Share your thoughts and experiences in the comments!

Top comments (0)