1 | [![SWR](https://assets.zeit.co/image/upload/v1572289618/swr/banner.png)](https://swr.now.sh)
|
2 |
|
3 | <p align="center">
|
4 | <a aria-label="SWR website" href="https://swr.now.sh">swr.now.sh<a>
|
5 | </p>
|
6 |
|
7 | <p align="center">
|
8 | <a aria-label="ZEIT logo" href="https://github.com/zeit">
|
9 | <img src="https://img.shields.io/badge/MADE%20BY%20ZEIT-000000.svg?style=for-the-badge&logo=ZEIT&labelColor=000000&logoWidth=20">
|
10 | </a>
|
11 | <a aria-label="NPM version" href="https://www.npmjs.com/package/swr">
|
12 | <img alt="" src="https://img.shields.io/npm/v/swr?style=for-the-badge&labelColor=000000">
|
13 | </a>
|
14 | <a aria-label="License" href="https://github.com/zeit/swr/blob/master/LICENSE">
|
15 | <img alt="" src="https://img.shields.io/npm/l/swr?style=for-the-badge&labelColor=000000">
|
16 | </a>
|
17 | </p>
|
18 |
|
19 | ## Intro
|
20 |
|
21 | SWR is a React Hooks library for remote data fetching.
|
22 |
|
23 | The name “**SWR**” is derived from `stale-while-revalidate`, a HTTP cache invalidation strategy popularized by [RFC 5861](https://tools.ietf.org/html/rfc5861).
|
24 | **SWR** first returns the data from cache (stale), then sends the fetch request (revalidate), and finally comes with the up-to-date data again.
|
25 |
|
26 | It features:
|
27 | - Transport and protocol agnostic data fetching
|
28 | - Fast page navigation
|
29 | - Revalidation on focus
|
30 | - Interval polling
|
31 | - Local mutation
|
32 | - Pagination
|
33 | - TypeScript ready
|
34 | - Suspense mode
|
35 | - Minimal API
|
36 |
|
37 | With SWR, components will get a stream of data updates constantly and automatically, Thus, the UI will be always fast and reactive.
|
38 |
|
39 | ## Quick Start
|
40 |
|
41 | ```js
|
42 | import useSWR from 'swr'
|
43 |
|
44 | function Profile () {
|
45 | const { data, error } = useSWR('/api/user', fetch)
|
46 |
|
47 | if (error) return <div>failed to load</div>
|
48 | if (!data) return <div>loading...</div>
|
49 | return <div>hello {data.name}!</div>
|
50 | }
|
51 | ```
|
52 |
|
53 | In this example, the React Hook `useSWR` accepts a `key` and a `fetch` function.
|
54 | `key` is a unique identifier of the data, normally a URL of the API. And the `fetch` accepts
|
55 | `key` as its parameter and returns the data asynchronously.
|
56 |
|
57 | `useSWR` also returns 2 values: `data` and `error`. When the request (fetch) is not yet finished,
|
58 | `data` will be `undefined`. And when we get a response, it sets `data` and `error` based on the result
|
59 | of `fetch` and rerenders the component.
|
60 |
|
61 | Note that `fetch` can be any asynchronous function, so you can use your favourite data-fetching
|
62 | library to handle that part.
|
63 |
|
64 | ## API
|
65 |
|
66 | ### `useSWR`
|
67 |
|
68 | ```js
|
69 | const {
|
70 | data, // data for the given key (or undefined)
|
71 | error, // error (or undefined)
|
72 | isValidating, // if the request is loading
|
73 | revalidate // function to trigger a validate manually
|
74 | } = useSWR(
|
75 | key, // a unique key for the data
|
76 | fn, // Promise returning function to fetch your data
|
77 | swrOptions? = {
|
78 | suspense: false, // enabled React Suspense mode
|
79 | revalidateOnFocus: true, // auto revalidate when window gets focused
|
80 | refreshWhenHidden: false, // refresh while the window is invisible
|
81 | shouldRetryOnError: true, // retry when fetch has an error
|
82 | refreshInterval: 0, // polling interval (disabled by default)
|
83 | errorRetryInterval: 5000, // error retry interval (10s on slow network)
|
84 | focusThrottleInterval: 5000, // keep focus revalidate requests in a time window
|
85 | dedupingInterval: 2000, // deduping requests
|
86 | loadingTimeout: 3000, // timeout for triggering the onLoadingSlow event
|
87 |
|
88 | onLoadingSlow, // event handlers
|
89 | onSuccess,
|
90 | onError,
|
91 | onErrorRetry,
|
92 |
|
93 | fetcher // default fetcher function (same as `fn`)
|
94 | }
|
95 | )
|
96 | ```
|
97 |
|
98 | ### `SWRConfig`
|
99 |
|
100 | A context to provide global configurations (`swrOptions`) for SWR.
|
101 |
|
102 | ```js
|
103 | import useSWR, { SWRConfig } from 'swr'
|
104 |
|
105 | function App () {
|
106 | // all the SWRs inside will use `refreshInterval: 1000`
|
107 | return <SWRConfig value={{ refreshInterval: 1000 }}>
|
108 | <Profile/>
|
109 | </SWRConfig>
|
110 | }
|
111 |
|
112 | function Profile () {
|
113 | const { data, error } = useSWR('/api/user', fetch)
|
114 | // ...
|
115 | }
|
116 | ```
|
117 |
|
118 | ### `mutate`
|
119 |
|
120 | With `mutate`, you can update your local data programmatically, while
|
121 | revalidating and finally replace it.
|
122 |
|
123 | ```js
|
124 | import useSWR, { mutate } from 'swr'
|
125 |
|
126 | function Profile () {
|
127 | const { data } = useSWR('/api/user', fetch)
|
128 |
|
129 | return <div>
|
130 | <h1>My name is {data.name}.</h1>
|
131 | <button onClick={async () => {
|
132 | const newName = data.name.toUpperCase()
|
133 | // send a request to the API to update the data
|
134 | await requestUpdateUsername(newName)
|
135 | // update the local data immediately and revalidate (refetch)
|
136 | mutate('/api/user', { ...data, name: newName })
|
137 | }}>Uppercase my name!</button>
|
138 | </div>
|
139 | }
|
140 | ```
|
141 |
|
142 | ### `trigger`
|
143 |
|
144 | You can broadcast a revalidation message to all SWR data inside any component by calling
|
145 | `trigger(key)`.
|
146 |
|
147 | ```js
|
148 | import useSWR, { trigger } from 'swr'
|
149 |
|
150 | function App () {
|
151 | return <div>
|
152 | <Profile />
|
153 | <button onClick={() => {
|
154 | // set the cookie as expired
|
155 | document.cookie = 'token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'
|
156 | // tell all SWRs with this key to revalidate
|
157 | trigger('/api/user')
|
158 | }}>
|
159 | Logout
|
160 | </button>
|
161 | </div>
|
162 | }
|
163 | ```
|
164 |
|
165 | ### Suspense Mode
|
166 |
|
167 | You can enable the `suspense` option to use `useSWR` with React Suspense.
|
168 |
|
169 | ```js
|
170 | import { Suspense } from 'react'
|
171 | import useSWR from 'swr'
|
172 |
|
173 | function Profile () {
|
174 | const { data } = useSWR('/api/user', fetch, { suspense: true })
|
175 | return <div>hello, {data.name}</div>
|
176 | }
|
177 |
|
178 | function App () {
|
179 | return <Suspense fallback={<div>loading...</div>}>
|
180 | <Profile/>
|
181 | </Suspense>
|
182 | }
|
183 | ```
|
184 |
|
185 | ## Authors
|
186 | - Shu Ding ([@shuding_](https://twitter.com/shuding_)) – [ZEIT](https://zeit.co)
|
187 | - Guillermo Rauch ([@rauchg](https://twitter.com/rauchg)) – [ZEIT](https://zeit.co)
|
188 | - Joe Haddad ([@timer150](https://twitter.com/timer150)) - [ZEIT](https://zeit.co)
|
189 | - Paco Coursey ([@pacocoursey](https://twitter.com/pacocoursey)) - [ZEIT](https://zeit.co)
|
190 |
|
191 | Thanks to Ryan Chen for providing the awesome `swr` npm package name!
|
192 |
|
193 | ## License
|
194 | The MIT License.
|