Skip to content

Commit 154b5c1

Browse files
docs: update persistQueryClient.md with Persister docs (#3356)
* docs: add idb example * docs: consolidate sections storing ~> persistQueryClientSave restoring ~> persistQueryClientRestore * docs: create section for persisters * docs: focus cacheTime docs persistQueryClient and createWebStoragePersister are unrelated * docs: add tip for indexed db * docs: cleanup intro * docs: note additional interfaces available * docs: reorder api to be more intuitive * docs: improve wording
1 parent 338da80 commit 154b5c1

File tree

1 file changed

+92
-65
lines changed

1 file changed

+92
-65
lines changed

docs/src/pages/plugins/persistQueryClient.md

Lines changed: 92 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3,128 +3,117 @@ id: persistQueryClient
33
title: persistQueryClient
44
---
55

6-
`persistQueryClient` is a utility for persisting the state of your queryClient and its caches for later use. Different **persisters** can be used to store your client and cache to many different storage layers.
6+
This is set of utilities for interacting with "persisters" which save your queryClient for later use. Different **persisters** can be used to store your client and cache to many different storage layers.
77

8-
## Officially Supported Persisters
8+
## Build Persisters
99

1010
- [createWebStoragePersister](/plugins/createWebStoragePersister)
1111
- [createAsyncStoragePersister](/plugins/createAsyncStoragePersister)
12+
- [create a custom persister](#persisters)
1213

13-
## Installation
14+
## How It Works
1415

15-
This utility comes packaged with `react-query` and is available under the `react-query/persistQueryClient` import.
16+
**IMPORTANT** - for persist to work properly, you probably want to pass `QueryClient` a `cacheTime` value to override the default during hydration (as shown above).
1617

17-
## Usage
18+
If it is not set when creating the `QueryClient` instance, it will default to `300000` (5 minutes) for hydration, and the stored cache will be discarded after 5 minutes of inactivity. This is the default garbage collection behavior.
1819

19-
Import the `persistQueryClient` function, and pass it your `QueryClient` instance (with a `cacheTime` set), and a Persister interface (there are multiple persister types you can use):
20+
It should be set as the same value or higher than persistQueryClient's `maxAge` option. E.g. if `maxAge` is 24 hours (the default) then `cacheTime` should be 24 hours or higher. If lower than `maxAge`, garbage collection will kick in and discard the stored cache earlier than expected.
2021

21-
```ts
22-
import { persistQueryClient } from 'react-query/persistQueryClient'
23-
import { createWebStoragePersister } from 'react-query/createWebStoragePersister'
22+
You can also pass it `Infinity` to disable garbage collection behavior entirely.
2423

24+
```ts
2525
const queryClient = new QueryClient({
2626
defaultOptions: {
2727
queries: {
2828
cacheTime: 1000 * 60 * 60 * 24, // 24 hours
2929
},
3030
},
3131
})
32-
33-
const localStoragePersister = createWebStoragePersister({
34-
storage: window.localStorage,
35-
})
36-
37-
persistQueryClient({
38-
queryClient,
39-
persister: localStoragePersister,
40-
})
4132
```
4233

43-
**IMPORTANT** - for persist to work properly, you need to pass `QueryClient` a `cacheTime` value to override the default during hydration (as shown above).
44-
45-
If it is not set when creating the `QueryClient` instance, it will default to `300000` (5 minutes) for hydration, and the stored cache will be discarded after 5 minutes of inactivity. This is the default garbage collection behavior.
46-
47-
It should be set as the same value or higher than persistQueryClient's `maxAge` option. E.g. if `maxAge` is 24 hours (the default) then `cacheTime` should be 24 hours or higher. If lower than `maxAge`, garbage collection will kick in and discard the stored cache earlier than expected.
48-
49-
You can also pass it `Infinity` to disable garbage collection behavior entirely.
34+
### Environment Checking
35+
A check for window `undefined` is performed prior to saving/restoring/removing your data (avoids build errors).
5036

51-
## How does it work?
37+
### Cache Busting
5238

53-
- A check for window `undefined` is performed prior to saving/restoring/removing your data (avoids build errors).
54-
55-
### Storing
56-
57-
As you use your application:
58-
59-
- When your query/mutation cache is updated, it will be [`dehydrated`](../reference/hydration#dehydrate) and stored by the persister you provided. The officially supported persisters throttle this action to happen at most every 1 second to save on potentially expensive writes, but can be customized as you see fit.
60-
61-
#### Cache Busting
62-
63-
Sometimes you may make changes to your application or data that immediately invalidate any and all cached data. If and when this happens, you can pass a `buster` string option to `persistQueryClient`, and if the cache that is found does not also have that buster string, it will be discarded.
39+
Sometimes you may make changes to your application or data that immediately invalidate any and all cached data. If and when this happens, you can pass a `buster` string option. If the cache that is found does not also have that buster string, it will be discarded. The following several functions accept this option:
6440

6541
```ts
6642
persistQueryClient({ queryClient, persister, buster: buildHash })
43+
persistQueryClientSave({ queryClient, persister, buster: buildHash })
44+
persistQueryClientRestore({ queryClient, persister, buster: buildHash })
6745
```
6846

69-
### Restoring
70-
71-
When you reload/bootstrap your app:
47+
### Removal
7248

73-
- Attempts to [`hydrate`](../reference/hydration#hydrate) a previously persisted dehydrated query/mutation cache from the persister back into the query cache of the passed query client.
74-
- If a cache is found that is older than the `maxAge` (which by default is 24 hours), it will be discarded. This can be customized as you see fit.
49+
If data is found to be any of the following:
7550

76-
### Removal
51+
1. expired (see `maxAge`)
52+
2. busted (see `buster`)
53+
3. error (ex: `throws ...`)
54+
4. empty (ex: `undefined`)
7755

78-
- If data is found to be expired (see `maxAge`), busted (see `buster`), error (ex: `throws ...`), or empty (ex: `undefined`), the persister `removeClient()` is called and the cache is immediately discarded.
56+
the persister `removeClient()` is called and the cache is immediately discarded.
7957

8058
## API
8159

82-
### `persistQueryClientRestore`
60+
### `persistQueryClientSave`
61+
62+
- Your query/mutation are [`dehydrated`](../reference/hydration#dehydrate) and stored by the persister you provided.
63+
- `createWebStoragePersister` and `createAsyncStoragePersister` throttle this action to happen at most every 1 second to save on potentially expensive writes. Review their documentation to see how to customize their throttle timing.
8364

84-
This will attempt to restore a persister's stored cached to the query cache of the passed queryClient.
65+
You can use this to explicitly persist the cache at the moment(s) you choose.
8566

8667
```ts
87-
persistQueryClientRestore({
68+
persistQueryClientSave({
8869
queryClient,
8970
persister,
90-
maxAge = 1000 * 60 * 60 * 24, // 24 hours
9171
buster = '',
92-
hydrateOptions = undefined,
72+
dehydrateOptions = undefined,
9373
})
9474
```
9575

96-
### `persistQueryClientSave`
76+
### `persistQueryClientSubscribe`
77+
78+
Runs `persistQueryClientSave` whenever the cache changes for your `queryClient`. For example: you might initiate the `subscribe` when a user logs-in and checks "Remember me".
9779

98-
This will attempt to save the current query cache with the persister. You can use this to explicitly persist the cache at the moments you choose.
80+
- It returns an `unsubscribe` function which you can use to discontinue the monitor; ending the updates to the persisted cache.
81+
- If you want to erase the persisted cache after the `unsubscribe`, you can send a new `buster` to `persistQueryClientRestore` which will trigger the persister's `removeClient` function and discard the persisted cache.
9982

10083
```ts
101-
persistQueryClientSave({
84+
persistQueryClientSubscribe({
10285
queryClient,
10386
persister,
10487
buster = '',
10588
dehydrateOptions = undefined,
10689
})
10790
```
10891

109-
### `persistQueryClientSubscribe`
92+
### `persistQueryClientRestore`
11093

111-
This will subscribe to query cache updates which will run `persistQueryClientSave`. For example: you might initiate the `subscribe` when a user logs-in and checks "Remember me".
94+
- Attempts to [`hydrate`](../reference/hydration#hydrate) a previously persisted dehydrated query/mutation cache from the persister back into the query cache of the passed query client.
95+
- If a cache is found that is older than the `maxAge` (which by default is 24 hours), it will be discarded. This timing can be customized as you see fit.
11296

113-
- It returns an `unsubscribe` function which you can use to discontinue the monitor; ending the updates to the persisted cache.
114-
- If you want to erase the persisted cache after the `unsubscribe`, you can send a new `buster` to `persistQueryClientRestore` which will trigger the persister's `removeClient` function and discard the persisted cache.
97+
You can use this to restore the cache at moment(s) you choose.
11598

11699
```ts
117-
persistQueryClientSubscribe({
100+
persistQueryClientRestore({
118101
queryClient,
119102
persister,
103+
maxAge = 1000 * 60 * 60 * 24, // 24 hours
120104
buster = '',
121-
dehydrateOptions = undefined,
105+
hydrateOptions = undefined,
122106
})
123107
```
124108

125109
### `persistQueryClient`
126110

127-
This will automatically restore any persisted cache and subscribes to the query cache to persist any changes from the query cache to the persister. It returns an `unsubscribe` function which you can use to discontinue the monitor; ending the updates to the persisted cache.
111+
Takes the following actions:
112+
113+
1. Immediately restores any persisted cache ([see `persistQueryClientRestore`](#persistqueryclientrestore))
114+
2. Subscribes to the query cache and returns the `unsubscribe` function ([see `persistQueryClientSubscribe`](#persistqueryclientsubscribe)).
115+
116+
This functionality is preserved from version 3.x.
128117

129118
```ts
130119
persistQueryClient({
@@ -139,7 +128,7 @@ persistQueryClient({
139128

140129
### `Options`
141130

142-
An object of options:
131+
All options available are as follows:
143132

144133
```ts
145134
interface PersistQueryClientOptions {
@@ -156,16 +145,25 @@ interface PersistQueryClientOptions {
156145
/** A unique string that can be used to forcefully
157146
* invalidate existing caches if they do not share the same buster string */
158147
buster?: string
159-
/** The options passed to the hydrate function */
148+
/** The options passed to the hydrate function
149+
* Not used on `persistQueryClientSave` or `persistQueryClientSubscribe` */
160150
hydrateOptions?: HydrateOptions
161-
/** The options passed to the dehydrate function */
151+
/** The options passed to the dehydrate function
152+
* Not used on `persistQueryClientRestore` */
162153
dehydrateOptions?: DehydrateOptions
163154
}
164155
```
165156

166-
## Building a Persister
157+
There are actually three interfaces available:
158+
- `PersistedQueryClientSaveOptions` is used for `persistQueryClientSave` and `persistQueryClientSubscribe` (doesn't use `hydrateOptions`).
159+
- `PersistedQueryClientRestoreOptions` is used for `persistQueryClientRestore` (doesn't use `dehydrateOptions`).
160+
- `PersistQueryClientOptions` is used for `persistQueryClient`
167161

168-
Persisters have the following interface:
162+
## Persisters
163+
164+
### Persisters Interface
165+
166+
Persisters have the following interfaces:
169167

170168
```ts
171169
export interface Persister {
@@ -185,4 +183,33 @@ export interface PersistedClient {
185183
}
186184
```
187185

188-
Satisfy all of these interfaces and you've got yourself a persister!
186+
You can import these (to build a persister):
187+
```ts
188+
import { PersistedClient, Persister } from "react-query/persistQueryClient";
189+
```
190+
191+
### Building A Persister
192+
You can persist however you like. Here is an example of how to build an [Indexed DB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) persister. Compared to `Web Storage API`, Indexed DB is faster, stores more than 5MB, and doesn't require serialization. That means it can readily store Javascript native types, such as `Date` and `File`.
193+
194+
```ts
195+
import { get, set, del } from "idb-keyval";
196+
import { PersistedClient, Persister } from "react-query/persistQueryClient";
197+
198+
/**
199+
* Creates an Indexed DB persister
200+
* @see https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
201+
*/
202+
export function createIDBPersister(idbValidKey: IDBValidKey = "reactQuery") {
203+
return {
204+
persistClient: async (client: PersistedClient) => {
205+
set(idbValidKey, client);
206+
},
207+
restoreClient: async () => {
208+
return await get<PersistedClient>(idbValidKey);
209+
},
210+
removeClient: async () => {
211+
await del(idbValidKey);
212+
},
213+
} as Persister;
214+
}
215+
```

0 commit comments

Comments
 (0)