What is SWR?
SWR stands for stale-while-revalidate. It's a caching strategy that provides a brilliant user experience. Here's the idea:
- When you request data, SWR first returns the stale data from its cache (if it exists). This makes the UI appear instantly.
- Then, in the background, it sends a network request to revalidate (fetch) the fresh data.
- Once the fresh data arrives, SWR updates the UI.
This means the user gets an immediate response, and the UI will automatically update to the latest version.
The Core Hook: useSWR
SWR's API is famously simple. The main hook, useSWR, takes two arguments:
- key: A unique identifier for the request. This is usually the URL of the API endpoint.
- fetcher: An async function that accepts the key and returns the data.
Code Example:
JavaScript
import useSWR from 'swr';
// The fetcher function can be a simple wrapper around fetch or a library like axios
const fetcher = (url) => fetch(url).then((res) => res.json());
function UserProfile({ userId }) {
// The useSWR hook returns data, error, and isLoading state
const { data, error, isLoading } = useSWR(
`/api/users/${userId}`, // The 'key' for this request
fetcher // The function to fetch the data
);
if (error) return <div>Failed to load user</div>;
if (isLoading) return <div>Loading...</div>;
// Once data is loaded, you can render it
return (
<div>
<h1>{data.name}</h1>
<p>Email: {data.email}</p>
</div>
);
}
That's it! SWR handles the loading state, error state, and caching for you.
Automatic Revalidation: The Magic of SWR ✨
This is where SWR truly shines. By default, it will automatically re-fetch your data in several scenarios, ensuring your UI is always fresh:
- Revalidation on Focus: When you switch to a different browser tab and then return, SWR refetches the data.
- Revalidation on Reconnect: If the user's network disconnects and then reconnects, SWR refetches.
- Revalidation on Interval: You can configure it to poll for new data on a set interval.
This makes SWR perfect for displaying real-time data or ensuring that long-lived browser tabs always have the latest information without any extra code.
Conditional Fetching
What if you need to wait for some data before you can make a request? For example, you need a user's ID before you can fetch their profile. You can do this by passing a null or falsy value as the key.
JavaScript
function UserAvatar() {
// First, get the user session
const { data: user } = useSWR('/api/session', fetcher);
const userId = user?.id;
// The request for the avatar will only be made AFTER the user ID is available.
// If `userId` is null or undefined, SWR will not start fetching.
const { data: avatar } = useSWR(userId ? `/api/avatars/${userId}` : null, fetcher);
if (!avatar) return <div className="skeleton-avatar" />;
return <img src={avatar.url} alt="User avatar" />;
}