![]()
SWR (stale-while-revalidate) is a React hook library that simplifies data fetching and caching. It provides a set of hooks to handle asynchronous data fetching and state management, making it easier to manage remote data in your React components.
SWR aims to optimize performance and UX by caching the data fetched from APIs and revalidating it in the background when necessary. It provides built-in mechanisms for retries, caching, and refetching data, making it a great choice for handling asynchronous state in React.
1. What is SWR?
SWR stands for “stale-while-revalidate,” which is a strategy for data fetching. It allows you to:
- Stale Data: Serve stale (old) data immediately while the new data is being fetched.
- Revalidate: Re-fetch the data in the background to keep it fresh and synchronized.
- Cache: Cache the data to avoid repeated requests for the same data.
The SWR library is built on top of React hooks and integrates seamlessly with React applications, making it easier to manage data fetching, caching, and updating the state.
2. Installing SWR
To start using SWR, you’ll first need to install it in your React application:
npm install swr
3. Basic Usage of SWR
SWR provides a hook called useSWR that handles the data fetching and caching logic.
Example: Fetching Data with SWR
import React from 'react';
import useSWR from 'swr';
// Function to fetch data
const fetcher = (url) => fetch(url).then((res) => res.json());
const App = () => {
const { data, error } = useSWR('https://api.example.com/data', fetcher);
if (error) return <div>Error loading data.</div>;
if (!data) return <div>Loading...</div>;
return (
<div>
<h1>API Data:</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
};
export default App;
Explanation:
useSWRtakes two arguments: the key (usually the URL or endpoint) and a fetcher function (a function that defines how to fetch the data).- SWR handles caching, background revalidation, and state management for the fetched data.
- If the data is still being fetched, SWR returns
nullfor the data and aloadingstate. - If an error occurs during fetching, SWR returns an
errorobject.
4. Caching with SWR
SWR automatically caches the results of the fetched data. When you request the same data again, SWR will return the cached data instantly (stale data) and re-fetch the data in the background to keep it updated.
Example: Cached Data with SWR
import React from 'react';
import useSWR from 'swr';
const fetcher = (url) => fetch(url).then((res) => res.json());
const App = () => {
const { data, error } = useSWR('https://api.example.com/data', fetcher);
if (error) return <div>Error loading data.</div>;
if (!data) return <div>Loading...</div>;
return (
<div>
<h1>API Data:</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
};
export default App;
In the above example, if the same API is requested multiple times (within the same component or across components), the cached response will be returned instantly, providing a faster user experience.
5. Revalidation with SWR
SWR uses a background revalidation strategy. When you fetch data, it doesn’t immediately block the UI and instead shows the cached (stale) data while fetching the new data in the background. Once the new data arrives, it updates the UI.
You can customize how frequently data should be revalidated using SWR’s configuration options.
Example: Revalidate Data Periodically
import React from 'react';
import useSWR from 'swr';
// Function to fetch data
const fetcher = (url) => fetch(url).then((res) => res.json());
const App = () => {
const { data, error } = useSWR('https://api.example.com/data', fetcher, {
refreshInterval: 5000, // Re-fetch data every 5 seconds
});
if (error) return <div>Error loading data.</div>;
if (!data) return <div>Loading...</div>;
return (
<div>
<h1>API Data:</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
};
export default App;
Explanation:
refreshIntervalallows you to set how frequently SWR should re-fetch data.- In the example above, data will be revalidated and updated every 5 seconds, ensuring the app always displays fresh data.
6. Error Handling with SWR
SWR provides an easy way to handle errors during data fetching by providing an error object in the returned result.
Example: Handling Errors with SWR
import React from 'react';
import useSWR from 'swr';
// Function to fetch data
const fetcher = (url) => fetch(url).then((res) => res.json());
const App = () => {
const { data, error } = useSWR('https://api.example.com/data', fetcher);
if (error) {
if (error.response) {
// Handle known API errors
return <div>API Error: {error.response.status}</div>;
}
return <div>Network Error: {error.message}</div>;
}
if (!data) return <div>Loading...</div>;
return (
<div>
<h1>API Data:</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
};
export default App;
Explanation:
- If an error occurs while fetching the data, SWR will return an error object. You can access the error message or response and handle it accordingly.
- This makes it easier to deal with both network errors and API-specific errors in a clean and manageable way.
7. Optimistic Data Updates with SWR
SWR also supports optimistic updates, where you can immediately reflect changes in the UI and then update the backend data in the background.
Example: Optimistic UI Updates with SWR
import React, { useState } from 'react';
import useSWR, { mutate } from 'swr';
// Function to fetch data
const fetcher = (url) => fetch(url).then((res) => res.json());
const updateData = async (newData) => {
await fetch('https://api.example.com/data', {
method: 'PUT',
body: JSON.stringify(newData),
});
return newData;
};
const App = () => {
const { data, error } = useSWR('https://api.example.com/data', fetcher);
const [newData, setNewData] = useState('');
const handleUpdate = async () => {
const optimisticData = { ...data, name: newData };
mutate('https://api.example.com/data', optimisticData, false); // Optimistic update
await updateData({ name: newData });
mutate('https://api.example.com/data'); // Revalidate the data
};
if (error) return <div>Error loading data.</div>;
if (!data) return <div>Loading...</div>;
return (
<div>
<h1>API Data:</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
<input
type="text"
value={newData}
onChange={(e) => setNewData(e.target.value)}
/>
<button onClick={handleUpdate}>Update Data</button>
</div>
);
};
export default App;
Explanation:
mutateis used to optimistically update the UI before the data is actually sent to the server.- In this example, when the user updates data, the UI is immediately updated with the new value, and the change is sent to the backend in the background.
- Once the backend update completes, the data is revalidated with
mutateto reflect the correct values.
Key Benefits of Using SWR:
- Automatic caching: Avoid redundant API calls by serving cached data.
- Revalidation: Ensure that data is always up-to-date without blocking the UI.
- Error handling: SWR simplifies managing and displaying error states.
- Optimistic UI: Instantly reflect changes in the UI for a better user experience.
By integrating SWR into your React app, you can handle asynchronous state efficiently and create applications that are faster, more reliable, and responsive.
