Getting started with SWR

  1. Installation
  2. Quick Start
  3. Make It Reusable
  4. API

SWR is a popular library which provides React Hooks for Data Fetching.

Installation

Inside your React project directory, run the following:

1
npm i swr

If you’re using yarn:

1
yarn add swr

Quick Start

For normal RESTful APIs with JSON data, first you need to create a fetcher function, which is just a wrapper of the native fetch:

1
const fetcher = (...args) => fetch(...args).then((res) => res.json());

If you’re using Axios:

1
2
3
4
5
6
7
8
import axios from "axios";

const fetcher = (url) => axios.get(url).then((res) => res.data);

function App() {
const { data, error } = useSWR("/api/data", fetcher);
// ...
}

Normally, there’re 3 possible states of a request: “loading”, “ready”, or “error”. You can use the value of data, error and isLoading to determine the current state of the request, and return the corresponding UI.

Make It Reusable

When building a web app, you might need to reuse the data in many places of the UI. It is incredibly easy to create reusable data hooks on top of SWR:

1
2
3
4
5
6
7
8
9
function useUser(id) {
const { data, error, isLoading } = useSWR(`/api/user/${id}`, fetcher);

return {
user: data,
isLoading,
isError: error,
};
}

And use it in your components:

1
2
3
4
5
6
7
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.

API

1
2
3
4
5
const { data, error, isLoading, isValidating, mutate } = useSWR(
key,
fetcher,
options
);

The key is required, it’s a unique key string for the request (or a function / array / null). The rest arguments are optional.

You can set initial data to be returned when the request is loading with the fallbackData attribute in the options.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import useSWR from "swr";
// The inital data
const initalState = {
name: "",
};
function fetcher(...args) {
return fetch(...args).then((res) => res.json());
}
function useUser(username) {
const { data, error, isLoading } = useSWR(
`https://api.github.com/users/${username}`,
fetcher,
{
// Set it as `fallbackData`
fallbackData: initalState,
}
);

return {
user: data,
isLoading,
isError: error,
};
}

export default function App() {
const { user, isLoading, isError } = useUser("rainyjune");
return (
<div className="App">
<h1>Hello {user.name}</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}

Demo: