Client-Side Data Fetching with SWR
The team behind Next.js has created a React hook library for data fetching called SWR. It is highly recommended if you are fetching data on the client side. It handles caching, revalidation, focus tracking, refetching on intervals, and more.
The name “SWR” is derived from stale-while-revalidate
, a HTTP cache invalidation strategy popularized by HTTP RFC 5861. SWR is a strategy to first return the data from the cache (stale), then send the fetch request (revalidate), and finally come with the up-to-date data.
Installation
npm i swr
Overview and use
import useSWR from'swr''
function Profile() {
const { data, error, isLoading } = useSWR('/api/user', fetcher)
if (error) return <div>failed to load</div>
if (isLoading) return <div>loading...</div>
return <div>hello {data.name}!</div>
}
Normally, there’re 3 possible states of a request: "loading," "ready," or "error.”. You can use the values of data
, error
and isLoading
to determine the current state of the request and return the corresponding UI.
Features
With just one single line of code, you can simplify the logic of data fetching in your project and also have all these amazing features out-of-the-box:
- Fast, lightweight and reusable data fetching
- Built-in cache and request deduplication
- Real-time experience
- Transport and protocol-agnostic
- SSR, ISR and SSG support
- TypeScript ready
- React Native
Example:
When building a web app, you might need to reuse the data in many parts of the UI. It is incredibly easy to create reusable data hooks on top of SWR.
function useUser (id) {
const { data, error, isLoading } = useSWR(`/api/user/${id}`, fetcher)
return {
user: data,
isLoading,
isError: error
}
}
And use it in your components:
function Avatar ({ id }) {
const { user, isLoading, isError } = useUser(id)
if (isLoading) return <Spinner />
if (isError) return <Error />
return <img src={user.avatar} />
}
By adopting this pattern, you can forget about fetching data in the imperative way: start the request, update the loading state, and return the final result. Instead, your code is more declarative; you just need to specify what data is used by the component.
Read More