@@ -3,7 +3,7 @@ id: manual-cache-updates
3
3
title : Manual Cache Updates
4
4
sidebar_label : Manual Cache Updates
5
5
hide_title : true
6
- description : ' RTK Query > Usage > Manual Cache Updates: Updating cached data manually'
6
+ description : ' RTK Query > Usage > Manual Cache Updates: Updating and creating cached data manually'
7
7
---
8
8
9
9
  ;
@@ -19,30 +19,51 @@ when it has been told that a mutation has occurred which would cause its data to
19
19
In most cases, we recommend using ` automated re-fetching ` as a preference over ` manual cache updates ` ,
20
20
unless you encounter the need to do so.
21
21
22
- However, in some cases, you may want to update the cache manually. When you wish to update cache
23
- data that _ already exists_ for query endpoints, you can do so using the
24
- [ ` updateQueryData ` ] ( ../api/created-api/api-slice-utils.mdx#updatequerydata ) thunk action
25
- available on the ` util ` object of your created API.
22
+ However, in some cases when refetch is not necessary, you may wish to update the cache data manually.
23
+ You can do it using provided by created API ` util ` object methods for both:
24
+
25
+ - updating already existing cache entries with [ ` updateQueryData ` ] ( ../api/created-api/api-slice-utils.mdx#updatequerydata )
26
+ - creating new or replacing existing cache entries with [ ` upsertQueryData ` ] ( ../api/created-api/api-slice-utils.mdx#upsertquerydata )
26
27
27
28
Anywhere you have access to the ` dispatch ` method for the store instance, you can dispatch the
28
29
result of calling ` updateQueryData ` in order to update the cache data for a query endpoint,
29
- if the corresponding cache entry exists.
30
+ if the corresponding cache entry exists or ` upsertQueryData ` to create new or replace existing one .
30
31
31
- Use cases for manual cache updates include:
32
+ ### Updating existing cache entries
33
+ For updates of existing cache entries use [ ` updateQueryData ` ] ( ../api/created-api/api-slice-utils.mdx#updatequerydata ) .
32
34
33
- - Providing immediate feedback to the user when a mutation is attempted
34
- - After a mutation, updating a single item in a large list of items that is already cached,
35
- rather than re-fetching the whole list
36
- - Debouncing a large number of mutations with immediate feedback as though they are being
37
- applied, followed by a single request sent to the server to update the debounced attempts
38
-
39
- :::note
40
35
` updateQueryData ` is strictly intended to perform _ updates_ to existing cache entries,
41
36
not create new entries. If an ` updateQueryData ` thunk action is dispatched that corresponds to
42
37
no existing cache entry for the provided ` endpointName ` + ` args ` combination, the provided ` recipe `
43
38
will not be called, and no ` patches ` or ` inversePatches ` will be returned.
39
+
40
+ Use cases for manual update of cache entries:
41
+ - Providing immediate feedback to the user when a mutation is attempted
42
+ - After a mutation, updating a single item in a large list of items that is already cached,
43
+ rather than re-fetching the whole list
44
+ - Debouncing a large number of mutations with immediate feedback as though they are being
45
+ applied, followed by a single request sent to the server to update the debounced attempts
46
+
47
+ ### Creating new cache entries or replacing existing ones
48
+ To create or replace existing cache entries use [ ` upsertQueryData ` ] ( ../api/created-api/api-slice-utils.mdx#upsertquerydata ) .
49
+
50
+ ` upsertQueryData ` is intended to perform _ replacements_ to existing cache entries or _ creation_ of new ones.
51
+ Due to the fact, that in ` upsertQueryData ` we do not have access to the previous state of the cache entry, since it can not exist yet,
52
+ the update may be performed only as a replacement. On the contrary, ` updateQueryData ` allows to perform a patching of the existing cache entry, but
53
+ can not create a new one.
54
+
55
+ :::tip
56
+
57
+ Manual creation of cache entries can introduce significant improvement in application performance and UX. Thanks to using the data we are already
58
+ aware of, we can avoid unnecessary requests and loaders.
59
+
44
60
:::
45
61
62
+ Use cases for upserting cache entries in pair with [ pessimistic updates] ( (../usage/manual-cache-updates.mdx#pessimistic-updates) ) :
63
+ - you create a new Post and backend returns its complete data including ` id ` . Then we
64
+ can use ` upsertQueryData ` to create a new cache entry for the ` getPostById(id) ` query, preventing unnecessary fetching it on enter.
65
+ - same can be applied for batch creations of items, when backend returns a list of created items with their ids.
66
+
46
67
## Recipes
47
68
48
69
### Optimistic Updates
@@ -57,7 +78,7 @@ The core concepts for an optimistic update are:
57
78
- when you start a query or mutation, ` onQueryStarted ` will be executed
58
79
- you manually update the cached data by dispatching ` api.util.updateQueryData ` within ` onQueryStarted `
59
80
- then, in the case that ` queryFulfilled ` rejects:
60
- - you roll it back via the ` .undo ` property of the object you got back from the earlier dispatch,
81
+ - you roll it back via the ` .undo ` property of the object you got back from the earlier dispatch,
61
82
OR
62
83
- you invalidate the cache data via ` api.util.invalidateTags ` to trigger a full re-fetch of the data
63
84
@@ -158,6 +179,8 @@ The core concepts for a pessimistic update are:
158
179
server in the ` data ` property
159
180
- you manually update the cached data by dispatching ` api.util.updateQueryData ` within
160
181
` onQueryStarted ` , using the data in the response from the server for your draft updates
182
+ - you manually create a new cache entry by dispatching ` api.util.upsertQueryData ` within ` onQueryStarted ` ,
183
+ using the complete Post object returned by backend.
161
184
162
185
``` ts title="Pessimistic update mutation example (async await)"
163
186
// file: types.ts noEmit
@@ -199,6 +222,23 @@ const api = createApi({
199
222
},
200
223
// highlight-end
201
224
}),
225
+ createPost: build .mutation <Post , Pick <Post , ' id' > & Partial <Post >>({
226
+ query : ({ id , ... body }) => ({
227
+ url: ` post/${id } ` ,
228
+ method: ' POST' ,
229
+ body ,
230
+ }),
231
+ // highlight-start
232
+ async onQueryStarted({ id }, { dispatch , queryFulfilled }) {
233
+ try {
234
+ const { data : createdPost } = await queryFulfilled
235
+ const patchResult = dispatch (
236
+ api .util .upsertQueryData (' getPost' , id , createdPost )
237
+ )
238
+ } catch {}
239
+ },
240
+ // highlight-end
241
+ }),
202
242
}),
203
243
})
204
244
```
0 commit comments