swr

SWR is a React Hooks library for remote data fetching.

The name “SWR” is derived from stale-while-revalidate, a HTTP cache invalidation strategy popularized by RFC 5861. SWR first returns the data from cache (stale), then sends the fetch request (revalidate), and finally comes with the up-to-date data again.

It features:

  • Transport and protocol agnostic data fetching
  • Fast page navigation
  • Revalidation on focus
  • Interval polling
  • Local mutation
  • Pagination
  • TypeScript ready
  • Suspense mode
  • Minimal API

With SWR, components will get a stream of data updates constantly and automatically, Thus, the UI will be always fast and reactive.

Quick Start

import useSWR from 'swr'

function Profile () {
  const { data, error } = useSWR('/api/user', fetch)

  if (error) return <div>failed to load</div>
  if (!data) return <div>loading...</div>
  return <div>hello {data.name}!</div>
}

In this example, the React Hook useSWR accepts a key and a fetch function.
key is a unique identifier of the data, normally a URL of the API. And the fetch accepts
key as its parameter and returns the data asynchronously.

useSWR also returns 2 values: data and error. When the request (fetch) is not yet finished,
data will be undefined. And when we get a response, it sets data and error based on the result
of fetch and rerenders the component.

Note that fetch can be any asynchronous function, so you can use your favourite data-fetching
library to handle that part.

API

useSWR

const {
  data,                                    // data for the given key (or undefined)
  error,                                   // error (or undefined)
  isValidating,                            // if the request is loading
  revalidate                               // function to trigger a validate manually
} = useSWR(
  key,                                     // a unique key for the data
  fn,                                      // Promise returning function to fetch your data
  swrOptions? = {
    suspense: false,                       // enabled React Suspense mode
    revalidateOnFocus: true,               // auto revalidate when window gets focused
    refreshWhenHidden: false,              // refresh while the window is invisible
    shouldRetryOnError: true,              // retry when fetch has an error
    refreshInterval: 0,                    // polling interval (disabled by default)
    errorRetryInterval: 5000,              // error retry interval (10s on slow network)
    focusThrottleInterval: 5000,           // keep focus revalidate requests in a time window
    dedupingInterval: 2000,                // deduping requests
    loadingTimeout: 3000,                  // timeout for triggering the onLoadingSlow event

    onLoadingSlow,                         // event handlers
    onSuccess,
    onError,
    onErrorRetry,

    fetcher                                // default fetcher function (same as `fn`)
  }
)

SWRConfig

A context to provide global configurations (swrOptions) for SWR.

import useSWR, { SWRConfig } from 'swr'

function App () {
  // all the SWRs inside will use `refreshInterval: 1000`
  return <SWRConfig value={{ refreshInterval: 1000 }}>
    <Profile/>
  </SWRConfig>
}

function Profile () {
  const { data, error } = useSWR('/api/user', fetch)
  // ...
}

mutate

With mutate, you can update your local data programmatically, while
revalidating and finally replace it.

import useSWR, { mutate } from 'swr'

function Profile () {
  const { data } = useSWR('/api/user', fetch)

  return <div>
    <h1>My name is {data.name}.</h1>
    <button onClick={async () => {
      const newName = data.name.toUpperCase()
      // send a request to the API to update the data
      await requestUpdateUsername(newName)
      // update the local data immediately and revalidate (refetch)
      mutate('/api/user', { ...data, name: newName })
    }}>Uppercase my name!</button>
  </div>
}

trigger

You can broadcast a revalidation message to all SWR data inside any component by calling
trigger(key).

import useSWR, { trigger } from 'swr'

function App () {
  return <div>
    <Profile />
    <button onClick={() => {
      // set the cookie as expired
      document.cookie = 'token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'
      // tell all SWRs with this key to revalidate
      trigger('/api/user')
    }}>
      Logout
    </button>
  </div>
}

Suspense Mode

You can enable the suspense option to use useSWR with React Suspense.

import { Suspense } from 'react'
import useSWR from 'swr'

function Profile () {
  const { data } = useSWR('/api/user', fetch, { suspense: true })
  return <div>hello, {data.name}</div>
}

function App () {
  return <Suspense fallback={<div>loading...</div>}>
    <Profile/>
  </Suspense>
}

GitHub