How to use SWR
By Flavio Copes
Learn how to use SWR in a Next.js app to fetch data with the useSWR hook and a fetcher function, handling the data, error, and isLoading states.
SWR is a React data fetching library made by Vercel. You give the useSWR hook a key (usually a URL) and a fetcher function, and it gives you back the data, plus loading and error states.
In a Next.js app, one of the best ways to do a GET request is to use SWR.
The name comes from stale-while-revalidate: SWR first returns the cached (stale) data it already has, then fires the request in the background, and finally updates the component with the fresh data. The result is a UI that feels instant, and stays up to date.
Setting it up
You install it with
npm install swr
and you have to define a fetcher function, I always use the same in a lib/fetcher.js file:
const fetcher = (...args) => fetch(...args).then((res) => res.json())
export default fetcher
The fetcher is just a function that takes the key and returns the data. SWR doesn’t fetch anything itself, it delegates to this function.
You import it at the top of your component’s file:
import fetcher from 'lib/fetcher'
Then you can start using it.
Fetching data
At the top of a component, import useSWR:
import useSWR from 'swr'
Then inside the component, at the top, we call useSWR to load the data we need:
const { data } = useSWR('/api/data', fetcher)
In addition to the data property, the object returned from useSWR contains error and isLoading. isLoading is especially useful to show some kind of “loading…” visual indication:
const { data, error, isLoading } = useSWR('/api/data', fetcher)
if (isLoading) return <p>Loading...</p>
if (error) return <p>Failed to load</p>
A nice side effect of the cache: if two components on the same page request /api/data, SWR deduplicates the calls. One request goes out, both components get the data.
Tuning revalidation
By default SWR revalidates when you focus the window, when the network reconnects, and in a few other cases. That’s great in production, but it can surprise you.
Here’s the pitfall I hit: in development, every time I switched from the editor back to the browser, SWR fired the request again, and I kept hammering my endpoint.
You can pass an additional object to useSWR with some options. I use this to limit the number of revalidations SWR does, so I don’t get repeated connections to the endpoint when I’m in development mode:
const { data } = useSWR('/api/data', fetcher, {
revalidateOnFocus: false,
revalidateOnReconnect: false,
refreshWhenOffline: false,
refreshWhenHidden: false,
refreshInterval: 0
})
One last trick: if you don’t want to fetch yet, pass null as the key. SWR skips the request entirely until the key becomes a real URL. Handy when the data depends on a user being logged in.
Related posts about js: