SWR
SWR is a React data-fetching library created around the idea "stale while revalidate".
It returns cached data quickly, then revalidates in the background to keep the UI fresh.
This pattern is useful for many read-heavy interfaces.
Basic SWR Usage
import useSWR from "swr";
async function fetcher(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error("Request failed");
}
return response.json();
}
function Profile({ userId }) {
const { data, error, isLoading } = useSWR(`/api/users/${userId}`, fetcher);
if (isLoading) return <p>Loading profile...</p>;
if (error) return <p role="alert">{error.message}</p>;
return <h1>{data.name}</h1>;
}The key identifies the request.
When the key changes, SWR fetches different data.
Conditional Fetching
Use null as the key when a request is not ready.
function Profile({ userId }) {
const { data } = useSWR(userId ? `/api/users/${userId}` : null, fetcher);
if (!userId) return <p>Select a user.</p>;
if (!data) return <p>Loading...</p>;
return <h1>{data.name}</h1>;
}This avoids requests with missing IDs.
Revalidation
SWR can revalidate when:
- a component mounts
- the browser window regains focus
- the network reconnects
- you manually call
mutate - a refresh interval is configured
This helps data stay fresh without writing custom effect logic.
Mutating Cached Data
mutate can update or refetch cached data.
import useSWR, { mutate } from "swr";
async function renameProject(projectId, name) {
await fetch(`/api/projects/${projectId}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name }),
});
mutate(`/api/projects/${projectId}`);
}After the update, SWR revalidates the project cache.
SWR vs TanStack Query
Both libraries manage server state.
SWR is often appreciated for a small API and read-heavy flows.
TanStack Query has a broader feature set around mutations, cache control, devtools, infinite queries, and complex invalidation.
Either can be a good choice depending on app needs and team preference.
Common Mistakes
- Using an unstable object as a key without understanding how it identifies the request.
- Forgetting conditional fetching when required values are missing.
- Treating stale data as always wrong instead of showing it during background revalidation.
- Using SWR for local UI state such as modals and tabs.
- Calling
mutateon the wrong key.
What does "stale while revalidate" mean in UI data fetching?
Practical Challenge
Create a UserMenu component with SWR.
It should:
- fetch
/api/me - show loading and error states
- render the user's name
- skip the request when the app is known to be logged out
Then add a refreshProfile button that calls mutate for the same key.
Recap
SWR is a focused server-state library built around cache-first rendering and background revalidation.
It is especially approachable for read-heavy data, while still supporting manual cache updates when needed.