DEV Community

Cover image for Discovering the Power of SWR: Streamlining Data Fetching in React
Nagakumar Reddy
Nagakumar Reddy

Posted on

Discovering the Power of SWR: Streamlining Data Fetching in React

When I first started working on data-driven React applications, one of my primary concerns was managing data fetching efficiently. Ensuring data was up-to-date while minimizing network requests seemed like a daunting task. Enter SWR, a revolutionary data fetching library for React that has transformed how I handle data in my projects. Let's dive into what SWR is, how it works, and how it can simplify your data fetching needs.

What is the SWR Library?

SWR, short for Stale-While-Revalidate, is a data fetching library for React that leverages an HTTP cache invalidation strategy to keep your data fresh. The SWR strategy works as follows:

  1. Stale: Return the data from the cache.
  2. Revalidate: Send a fetch request to get the up-to-date data.
  3. Update: Return the latest data after fetching.

This approach ensures that the data displayed to users is always up-to-date while minimizing redundant network requests.

Key Concepts of SWR

Caching

SWR automatically caches the fetched data, allowing your application to serve data quickly without making redundant network requests. The cache duration can be time-based or event-based (e.g., reconnecting to the Internet), ensuring optimal performance and up-to-date information.

Revalidation

When cached data becomes stale, SWR revalidates it by re-fetching it from the server. Revalidation is automatically triggered:

  • Every time the component mounts, even if data is in the cache.
  • When the window gains focus.
  • When the browser regains its network connection.

How to Use the useSWR Hook

The useSWR hook is the main hook provided by SWR for data fetching. Here's how to use it:

Parameters

  • key: A unique identifier for the request (e.g., a URL).
  • fetcher: An async function that accepts the key and returns the data. SWR passes the key to the fetcher function when loading the data.
  • options: An object of options for customizing the behavior of the hook (e.g., cache time).

Returned Object

  • data: The data returned from the fetcher function (initially undefined).
  • error: The error thrown by the fetcher function (initially undefined).
  • isLoading: A boolean indicating the loading status of the first request.
  • isValidating: A boolean indicating the validation status of each request.
  • mutate: A function to manually trigger a revalidation.

Example Usage

Here's a simple example of how to use the useSWR hook in a React component:

import useSWR from 'swr';

const fetcher = async (url) => {
  const response = await fetch(url);
  if (!response.ok) {
    throw new Error('Network response was not ok');
  }
  return response.json();
};

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

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

  return (
    <div>
      <h1>Data</h1>
      <pre>{JSON.stringify(data, null, 2)}</pre>
      <button onClick={() => mutate()}>Refresh</button>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

How I Used SWR in My Project

For my Front End Libraries Certification project on freeCodeCamp, I integrated SWR to manage data fetching seamlessly. Although the project was written in TypeScript, I'll provide examples in JavaScript for simplicity.

Project Example

Here's a basic example of using SWR with an API endpoint:

import useSWR from 'swr';

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

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

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

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

export default MyComponent;
Enter fullscreen mode Exit fullscreen mode

Using SWRConfig for Global Configuration

The SWRConfig component in SWR is a context provider that allows you to set global configurations for all SWR hooks in your application. By using SWRConfig, you can define default behaviors and options for data fetching, caching, and revalidation, which will apply to all instances of useSWR unless overridden at the individual hook level.

How to Use SWRConfig

Step 1: Import SWRConfig

First, import the SWRConfig component from the swr library.

import { SWRConfig } from 'swr';
Enter fullscreen mode Exit fullscreen mode
Step 2: Wrap Your Application with SWRConfig

Wrap your application (or a part of it) with the SWRConfig provider. You can place it at the root of your application to apply the configurations globally.

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { SWRConfig } from 'swr';

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

ReactDOM.render(
  <SWRConfig
    value={{
      fetcher,
      dedupingInterval: 2000,
      shouldRetryOnError: false,
      revalidateOnFocus: true,
      revalidateOnReconnect: true,
    }}
  >
    <App />
  </SWRConfig>,
  document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode
Step 3: Access Global Configurations in useSWR Hooks

Now, all useSWR hooks within the SWRConfig context will use the global configurations provided.

import useSWR from 'swr';

function MyComponent() {
  const { data, error, isLoading } = useSWR('/api/my-data');

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

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

export default MyComponent;
Enter fullscreen mode Exit fullscreen mode

Example Configuration Options

Here are some common configuration options you can pass to SWRConfig:

  • fetcher: The default fetcher function for all useSWR hooks.
  • dedupingInterval: The interval in milliseconds to deduplicate requests. Default is 2000ms.
  • shouldRetryOnError: Whether to automatically retry on errors. Default is true.
  • revalidateOnFocus: Whether to revalidate when the window gains focus. Default is true.
  • revalidateOnReconnect: Whether to revalidate when the browser regains network connection. Default is true.
  • refreshInterval: The interval in milliseconds for polling data. Default is 0 (no polling).

Advanced Usage: Nested SWRConfig

You can nest SWRConfig providers to apply different configurations to different parts of your application. For example:

import { SWRConfig } from 'swr';
import MyComponent from './MyComponent';
import AnotherComponent from './AnotherComponent';

const App = () => (
  <SWRConfig value={{ fetcher: (url) => fetch(url).then((res) => res.json()) }}>
    <MyComponent />
    <SWRConfig value={{ fetcher: (url) => axios.get(url).then((res) => res.data) }}>
      <AnotherComponent />
    </SWRConfig>
  </SWRConfig>
);

export default App;
Enter fullscreen mode Exit fullscreen mode

In this example, MyComponent will use the default fetcher, while AnotherComponent will use an axios-based fetcher.

Conclusion

SWR simplifies data fetching in React by providing automatic caching, revalidation, and a straightforward API. It helps ensure your application always displays up-to-date data while reducing the complexity of managing data fetching manually.

Using SWRConfig helps you centralize and manage the configurations for all data fetching operations in your React application. This makes it easier to maintain consistent behaviors and reduces redundancy, especially when dealing with multiple data-fetching components.

Embracing SWR in my projects has significantly improved my workflow, allowing me to focus more on building features rather than managing data fetching intricacies. Whether you're working on a small project or a large-scale application, SWR can help streamline your data fetching and keep your app responsive and up-to-date.

Top comments (0)