How to use SWR

By

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: