UNPKG

8.43 kBMarkdownView Raw
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?logo=ZEIT&labelColor=000000&logoWidth=12">
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">
13 </a>
14 <a aria-label="Package size" href="https://bundlephobia.com/result?p=swr">
15 <img alt="" src="https://img.shields.io/bundlephobia/minzip/swr">
16 </a>
17 <a aria-label="License" href="https://github.com/zeit/swr/blob/master/LICENSE">
18 <img alt="" src="https://img.shields.io/npm/l/swr">
19 </a>
20</p>
21
22## Intro
23
24SWR is a React Hooks library for remote data fetching.
25
26The name “**SWR**” is derived from `stale-while-revalidate`, a HTTP cache invalidation strategy popularized by [RFC 5861](https://tools.ietf.org/html/rfc5861).
27**SWR** first returns the data from cache (stale), then sends the fetch request (revalidate), and finally comes with the up-to-date data again.
28
29It features:
30- Transport and protocol agnostic data fetching
31- Fast page navigation
32- Revalidation on focus
33- Interval polling
34- Local mutation
35- Pagination
36- TypeScript ready
37- Suspense mode
38- Minimal API
39
40With SWR, components will get a stream of data updates constantly and automatically, Thus, the UI will be always fast and reactive.
41
42## Quick Start
43
44To install, run `yarn add swr` or `npm install swr` in your React project.
45
46```js
47import useSWR from 'swr'
48
49function Profile () {
50 const { data, error } = useSWR('/api/user', fetcher)
51
52 if (error) return <div>failed to load</div>
53 if (!data) return <div>loading...</div>
54 return <div>hello {data.name}!</div>
55}
56```
57
58In this example, the React Hook `useSWR` accepts a `key` and a `fetcher` function.
59`key` is a unique identifier of the data, normally a URL of the API. And the `fetcher` accepts
60`key` as its parameter and returns the data asynchronously.
61
62`useSWR` also returns 2 values: `data` and `error`. When the request (fetcher) is not yet finished,
63`data` will be `undefined`. And when we get a response, it sets `data` and `error` based on the result
64of `fetcher` and rerenders the component.
65
66Note that `fetcher` can be any asynchronous function, so you can use your favourite data-fetching
67library to handle that part.
68
69---
70
71- API
72 - [`useSWR`](#useswr)
73 - [`SWRConfig`](#swrconfig)
74 - [`mutate`](#mutate)
75 - [`trigger`](#trigger)
76- Examples
77 - [Suspense Mode](#suspense-mode)
78 - [Subscription (e.g.: socket.io)](#subscription-eg-socketio)
79 - [Dependent Fetching](#dependent-fetching)
80
81## API
82
83### `useSWR`
84
85```js
86const {
87 data, // data for the given key (or undefined)
88 error, // error (or undefined)
89 isValidating, // if the request is loading
90 revalidate // function to trigger a validate manually
91} = useSWR(
92 key, // a unique key for the data (or a function, see below)
93 fetcher, // Promise returning function to load your data
94 swrOptions? = {
95 suspense: false, // enabled React Suspense mode
96 revalidateOnFocus: true, // auto revalidate when window gets focused
97 refreshWhenHidden: false, // refresh while the window is invisible
98 shouldRetryOnError: true, // retry when fetcher has an error
99 refreshInterval: 0, // polling interval (disabled by default)
100 errorRetryInterval: 5000, // error retry interval (10s on slow network)
101 focusThrottleInterval: 5000, // keep focus revalidate requests in a time window
102 dedupingInterval: 2000, // deduping requests
103 loadingTimeout: 3000, // timeout for triggering the onLoadingSlow event
104
105 onLoadingSlow, // event handlers
106 onSuccess,
107 onError,
108 onErrorRetry,
109
110 fetcher // default fetcher function
111 }
112)
113```
114
115#### `key` as a function
116
117Pass a function as the `key` to `useSWR` to conditionally fetch data. If the functions throws an error or returns a falsy value, SWR will cancel the request.
118
119```js
120// key returns a falsy value
121const { data } = useSWR(() => shouldFetch ? '/api/data' : null, fetcher)
122
123// key throws an error when user.id is not defined
124const { data } = useSWR(() => '/api/data?uid=' + user.id, fetcher)
125```
126
127### `SWRConfig`
128
129A context to provide global configurations (`swrOptions`) for SWR.
130
131```js
132import useSWR, { SWRConfig } from 'swr'
133
134function App () {
135 // all the SWRs inside will use `refreshInterval: 1000`
136 // and the native `fetch` implementation
137 return <SWRConfig value={{
138 refreshInterval: 1000,
139 fetcher: (...args) => fetch(...args).then(res => res.json())
140 }}>
141 <Profile/>
142 </SWRConfig>
143}
144
145function Profile () {
146 const { data, error } = useSWR('/api/user')
147 // ...
148}
149```
150
151### `mutate`
152
153With `mutate`, you can update your local data programmatically, while
154revalidating and finally replace it.
155
156```js
157import useSWR, { mutate } from 'swr'
158
159function Profile () {
160 const { data } = useSWR('/api/user', fetcher)
161
162 return <div>
163 <h1>My name is {data.name}.</h1>
164 <button onClick={async () => {
165 const newName = data.name.toUpperCase()
166 // send a request to the API to update the data
167 await requestUpdateUsername(newName)
168 // update the local data immediately and revalidate (refetch)
169 mutate('/api/user', { ...data, name: newName })
170 }}>Uppercase my name!</button>
171 </div>
172}
173```
174
175### `trigger`
176
177You can broadcast a revalidation message to all SWR data inside any component by calling
178`trigger(key)`.
179
180```js
181import useSWR, { trigger } from 'swr'
182
183function App () {
184 return <div>
185 <Profile />
186 <button onClick={() => {
187 // set the cookie as expired
188 document.cookie = 'token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'
189 // tell all SWRs with this key to revalidate
190 trigger('/api/user')
191 }}>
192 Logout
193 </button>
194 </div>
195}
196```
197
198## Examples
199
200### Suspense Mode
201
202You can enable the `suspense` option to use `useSWR` with React Suspense.
203
204```js
205import { Suspense } from 'react'
206import useSWR from 'swr'
207
208function Profile () {
209 const { data } = useSWR('/api/user', fetcher, { suspense: true })
210 return <div>hello, {data.name}</div>
211}
212
213function App () {
214 return <Suspense fallback={<div>loading...</div>}>
215 <Profile/>
216 </Suspense>
217}
218```
219
220### Subscription (e.g.: socket.io)
221
222You can use SWR with socket.io (generally any subscription pattern) like this:
223
224```js
225// fetch-data.js
226
227import { mutate } from 'swr'
228
229let latestData = null
230
231// setup ws and broadcast to all SWRs
232...
233socket.on('data', data => {
234 latestData = data
235 mutate('/api/data', data, false)
236})
237
238export default () => latestData
239```
240
241and your component:
242
243```js
244import useSWR from 'swr'
245import fetchData from './fetch-data'
246
247function App () {
248 const { data } = useSWR('/api/data', fetchData)
249 // ...
250}
251```
252
253### Dependent Fetching
254SWR allows you to fetch data that depends on other data. It ensures the maximum possible parallelism (avoiding waterfalls), as well as serial fetching when a piece of dynamic data is required for the next data fetch to happen.
255
256```js
257import useSWR from 'swr'
258
259function MyProjects () {
260 const { data: user } = useSWR('/api/user')
261 const { data: projects } = useSWR(
262 () => '/api/projects?uid=' + user.id
263 )
264 // When passing a function, SWR will use the
265 // return value as `key`. If the function throws,
266 // SWR will know that some dependencies are not
267 // ready. In this case it is `user`.
268
269 if (!projects) return 'loading...'
270 return 'You have ' + projects.length + ' projects'
271}
272```
273
274## Authors
275- Shu Ding ([@shuding_](https://twitter.com/shuding_)) – [ZEIT](https://zeit.co)
276- Guillermo Rauch ([@rauchg](https://twitter.com/rauchg)) – [ZEIT](https://zeit.co)
277- Joe Haddad ([@timer150](https://twitter.com/timer150)) - [ZEIT](https://zeit.co)
278- Paco Coursey ([@pacocoursey](https://twitter.com/pacocoursey)) - [ZEIT](https://zeit.co)
279
280Thanks to Ryan Chen for providing the awesome `swr` npm package name!
281
282## License
283The MIT License.