2019-10-29

useSWR - React Hooks for Remote Data Fetching

react, hooks

banner

Image by analogicus from Pixabay

Zeit has released a React hook, useSWR, which has a tag-line, "React Hooks for Remote Data Fetching".

SWR stands for, well, check out the site to see what it means (😉).

It does what it claims to do, and do it well and easily.

"Well"

useSWR boasts following features.

  • Lightweight
  • Backend agnostic
  • Realtime
  • JAMstack oriented
  • Suspense
  • TypeScript ready
  • REST compatible
  • Remote + Local

"Easy"

Suspense

Yes. It works with the experimental channel of React's Suspense.

All you need is to set the suspense: true as one of the options in the API.

1const { data } = useSWR(2  "https://jsonplaceholder.typicode.com/posts",3  url =>4    fetch(url)5      .then(_ => _.json())6      .then(sleep),7  { suspense: true },8);

Fetching data.

Home page shows the following basic example.

1import useSWR from '@zeit/swr'2
3function Profile () {4                                               1️⃣ 👇5  const { data, error } = useSWR('/api/user', fetch)6
7  if (error) return <div>failed to load</div>8  if (!data) return <div>loading...</div>9  return <div>hello {data.name}!</div>10}

In this example, the React Hook useSWR accepts a key and a fetch function. key is a unique identifier of the data, normally the URL of the API. Then key will be passed to fetch, which returns the data asynchronously.

I was kind of lost with 1️⃣ fetch as I was expecting to pass fetch and expected useSWR to auto convert the response to a json string as axios does but it doesn't.

So using the pattern in the basic example, you might want to pass your own method, which fetches data, and transforms it into a json (refer to getRandomDog method below).

1const getRandomDog = url => fetch(url).then(_ => _.json());2
3// https://swr.now.sh/#basic-data-loading4function BasicDataLoading() {5  const { error, data } = useSWR(`https://dog.ceo/api/breeds/image/random`, getRandomDog);6
7  return (8    <>9      {error && <p>Error! {error}</p>}10      {data && data.status === "success" && <img src={data.message} alt={data.message} />}11    </>12  );13}

I found it to work like a function, which accepts the key ('/api/user' in the basic example) and "you" as a caller decide how to return a value. Be it an async method, or synchronous method, it didn't matter when I tried.

1const getCachedText = async text => text;2const options = {3  revalidateOnFocus: false,4  shouldRetryOnError: false,5};6function CachedHeader() {7  const { data: cachedText } = useSWR("Cached Header", getCachedText, options);8
9  return <h1>{cachedText}</h1>;10}11
12function Identity({ value }) {13  const { data } = useSWR(value, () => value, options);14
15  return <>{data}</>;16}

Sandbox

I've created a sandbox to play around & learn the library.
Fork it and play around :)

Note: It uses an experimental version of React (it can break anytime)

https://codesandbox.io/s/having-fun-with-useswr-lsjjx

Parting Words

This post is created within an hour just to log & share the excitement 🎉

Check out the project page, https://swr.now.sh/ to learn more and learn more on the GitHub repo, https://github.com/zeit/swr.