Skip to main content
Featured Article

SWR: Enhance Your React Applications with Efficient Data Fetching

SWR is a powerful React hook for data fetching that simplifies the process of managing remote and local data. With features like real-time updates, caching, and automatic revalidation, SWR ensures your UI remains fast and responsive. Ideal for both client-side and server-side applications, SWR enhances the developer experience by providing a lightweight and efficient way to handle data fetching.

  • 5 MIN
  • Pankaj Kumar
Updated: coding

Share

  • Whatsapp Icon
  • Twitter Icon
  • Telegram Icon
  • Linkedin Icon
  • Facebook Icon
SWR: Enhance Your React Applications with Efficient Data Fetching
coding 5 min read

SWR is a powerful React hook for data fetching that simplifies the process of managing remote and local data. With features like real-time updates, caching, and automatic revalidation, SWR ensures your UI remains fast and responsive. Ideal for both client-side and server-side applications, SWR enhances the developer experience by providing a lightweight and efficient way to handle data fetching.

SWR (Stale-While-Revalidate) is a React Hooks library for data fetching that simplifies the process of managing server state in your applications. It enhances user experience by providing fast, real-time updates and handling various fetching scenarios seamlessly.

With SWR, components continuously receive real-time data updates, ensuring that the UI remains fast and responsive.

Features

  • Lightweight: Minimal overhead for fast performance.
  • Realtime: Data is kept fresh and updated.
  • Suspense: Support for React Suspense for smoother loading states.
  • Pagination: Easy handling of paginated data.
  • Backend Agnostic: Works with any backend or API.
  • SSR/SSG Ready: Supports Server-Side Rendering (SSR) and Static Site Generation (SSG).
  • TypeScript Ready: Fully compatible with TypeScript.
  • Remote + Local: Can handle both remote and local data sources.

The name “SWR” is derived from stale-while-revalidate, a cache invalidation strategy popularized by HTTP RFC 5861. This strategy first returns stale data from the cache, sends a fetch request to revalidate, and ultimately returns the most up-to-date data. With SWR, components receive a continuous stream of data updates, ensuring that the UI is always fast and reactive.

Installation

To get started with SWR, install the library using npm or yarn:

Using npm:

npm install swr

or Using yarn:

yarn add swr

Basic Usage

Once installed, you can use SWR in your React components. Here’s a basic example of how to fetch data from an API:

import React from 'react';
import useSWR from 'swr';

// Fetcher function to get data from API
const fetcher = (url: string) => fetch(url).then(res => res.json());

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

  if (error) return <div>Failed to load user data</div>;
  if (isLoading) return <div>Loading...</div>;

  return <div>Hello, {data.name}!</div>;
}

Key Concepts

  • Fetcher Function: A function that defines how to fetch your data. This can be any asynchronous function, including fetch or Axios.
  • Key: A unique identifier (usually the API URL) used by SWR to manage cached data.

SWR API

The useSWR hook returns several values that help you manage your data and UI state effectively:

const { data, error, mutate } = useSWR('/api/user', fetcher);

Return Values

  • data: The fetched data (or undefined if not yet loaded).
  • error: An error object (or undefined if there’s no error).
  • isLoading: A boolean indicating if the data is currently being loaded.
  • isValidating: A boolean indicating if the data is currently being revalidated.
  • mutate: A function to mutate the cached data (i.e., to update or refetch it).

Example with Mutate

const { data, error, mutate } = useSWR('/api/user', fetcher);

// To mutate the data
const updateUserData = async (newData) => {
  await fetch('/api/user', {
    method: 'POST',
    body: JSON.stringify(newData),
  });

  // Revalidate data
  mutate('/api/user');
};

Advanced Usage and Options

SWR provides various options to customize its behavior, improving user experience and data handling.

Options Overview

  • suspense: Enable React Suspense mode (default is false). When enabled, SWR can throw a promise while loading, allowing you to use React’s built-in Suspense features.

  • revalidateOnFocus: Automatically revalidates when the window gains focus (default is true).

  • refreshInterval: Set a polling interval in milliseconds for automatic refresh. You can pass a number or a function that returns a number.

  • fallbackData: Initial data to be returned while the fetcher function is running, ensuring that users see something rather than an empty state.

  • keepPreviousData: Return the previous key’s data until the new data has been loaded, helping maintain a smoother user experience during transitions.

  • shouldRetryOnError: Automatically retries failed requests (default is true).

  • dedupingInterval: Prevents SWR from making multiple requests for the same key within this time span (in milliseconds, default is 2000).

Example with Options

const { data, error } = useSWR('/api/user', fetcher, {
  revalidateOnFocus: true,
  refreshInterval: 5000, // refresh every 5 seconds
  fallbackData: { name: 'Loading...' },
  keepPreviousData: true, // keep old data until new data is fetched
});

Using a Global Configuration

You can also set global configuration options for all SWR hooks by using SWRConfig: import { SWRConfig } from ‘swr’;

function App() {
  return (
    <SWRConfig value={{
      refreshInterval: 3000,
      revalidateOnFocus: false,
      fetcher: (url) => fetch(url).then(res => res.json())
    }}>
      <UserProfile />
    </SWRConfig>
  );
}

Pagination and Fetching Data

SWR can easily handle pagination by using dynamic keys. Here’s an example:

Example for Pagination

function PaginatedUsers({ page }) {
  const { data, error } = useSWR(`/api/users?page=${page}`, fetcher);

  if (error) return <div>Failed to load users</div>;
  if (!data) return <div>Loading...</div>;

  return (
    <ul>
      {data.users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

Additional Features

SWR includes a rich set of features to enhance data fetching:

  1. Fast, lightweight, and reusable data fetching: SWR is optimized for performance, ensuring quick data retrieval.
  2. Built-in cache and request deduplication: Prevents duplicate requests, enhancing efficiency.
  3. Real-time experience: Updates data in real-time to reflect changes.
  4. Transport and protocol agnostic: Works with various data sources.
  5. SSR / ISR / SSG support: Seamless integration with different rendering methods.
  6. TypeScript ready: Easily integrates into TypeScript projects.

Error Handling

You can handle errors gracefully using the error value returned from useSWR. Here’s how to provide user feedback on error states:

if (error) {
  if (error.response) {
    return <div>Error: {error.response.status} {error.response.statusText}</div>;
  }
  return <div>Failed to load data</div>;
}

Usage Example

import useSWR, { SWRConfig } from 'swr';

const url = '<https://dummyjson.com/users>';

// Custom fetcher function
const fetcher = async (url: any) => {
  const res = await fetch(url);
  if (!res.ok) {
    const error: any = new Error('An error occurred while fetching the data.');
    error.info = await res.json();
    error.status = res.status;
    throw error;
  }
  return res.json();
};

const id = 30;

// Create Custom Hook
export function useUser(id: any) {
  const { data, error, isLoading } = useSWR(`${url}/${id}`, fetcher, { suspense: true, fallback: <Spinner />, refreshInterval: 1000000 });
  return {
    user: data,
    isLoading,
    isError: error,
  };
}

// Child components
function Spinner() {
  return <div>Loading...</div>;
}

function Avatar() {
  const { user, isLoading } = useUser(id);
  if (isLoading) return <Spinner />;
  return <img src={user?.image} width={40} className='border rounded-pill' alt={user?.username} />;
}

function Navbar() {
  return (
    <div>
      <Avatar />
    </div>
  );
}

function Content() {
  const { user, isLoading } = useUser(id);
  if (isLoading) return <Spinner />;
  return (
    <>
      <h1>Welcome back, {user.username}</h1>
    </>
  );
}

const SWRFetch = () => {
  return (
    <SWRConfig
      value={{
        refreshInterval: 3000,
        fetcher: fetcher,
      }}
    >
      <Navbar />
      <Content />
    </SWRConfig>
  );
};

export default SWRFetch;

Explanation

Fetcher Function The fetcher function is an asynchronous function that fetches data from the given URL. If the response is not okay, it throws an error with additional information.

Custom Hook The useUser custom hook utilizes the useSWR hook to fetch user data based on the provided ID. It returns the user data, loading state, and error state.

Components

  1. Spinner: A simple loading spinner component displayed while data is being fetched.
  2. Avatar: This component displays the user’s avatar image.
  3. Navbar: This component includes the Avatar component.
  4. Content: Displays a welcome message using the fetched user data.

SWR Configuration The SWRConfig component wraps the Navbar and Content components, providing global configuration for SWR, including a refresh interval and the fetcher function.

Conclusion

SWR provides a robust and flexible API for data fetching in React applications. Its combination of features, such as caching, revalidation, and real-time updates, makes it a powerful choice for modern web applications. By leveraging its capabilities, you can enhance the performance and user experience of your projects.

For more details and advanced usage, refer to the official SWR documentation

Explore Related Topics

Stay Updated with Our Latest Articles

Subscribe to our newsletter and get exclusive content, tips, and insights delivered directly to your inbox.

We respect your privacy. Unsubscribe at any time.

About the Author

pankaj kumar - Author

pankaj kumar

Blogger

er....@gma....com