Skip to content

Commit 6c98f73

Browse files
committed
docs: extend manual cache management by upsertQueryData description and example
(cherry picked from commit 86b8f71)
1 parent e929938 commit 6c98f73

File tree

1 file changed

+55
-15
lines changed

1 file changed

+55
-15
lines changed

docs/rtk-query/usage/manual-cache-updates.mdx

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ id: manual-cache-updates
33
title: Manual Cache Updates
44
sidebar_label: Manual Cache Updates
55
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'
77
---
88

99
 
@@ -19,30 +19,51 @@ when it has been told that a mutation has occurred which would cause its data to
1919
In most cases, we recommend using `automated re-fetching` as a preference over `manual cache updates`,
2020
unless you encounter the need to do so.
2121

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)
2627

2728
Anywhere you have access to the `dispatch` method for the store instance, you can dispatch the
2829
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.
3031

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).
3234

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
4035
`updateQueryData` is strictly intended to perform _updates_ to existing cache entries,
4136
not create new entries. If an `updateQueryData` thunk action is dispatched that corresponds to
4237
no existing cache entry for the provided `endpointName` + `args` combination, the provided `recipe`
4338
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+
4460
:::
4561

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+
4667
## Recipes
4768

4869
### Optimistic Updates
@@ -57,7 +78,7 @@ The core concepts for an optimistic update are:
5778
- when you start a query or mutation, `onQueryStarted` will be executed
5879
- you manually update the cached data by dispatching `api.util.updateQueryData` within `onQueryStarted`
5980
- 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,
6182
OR
6283
- you invalidate the cache data via `api.util.invalidateTags` to trigger a full re-fetch of the data
6384

@@ -158,6 +179,8 @@ The core concepts for a pessimistic update are:
158179
server in the `data` property
159180
- you manually update the cached data by dispatching `api.util.updateQueryData` within
160181
`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.
161184

162185
```ts title="Pessimistic update mutation example (async await)"
163186
// file: types.ts noEmit
@@ -199,6 +222,23 @@ const api = createApi({
199222
},
200223
// highlight-end
201224
}),
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+
}),
202242
}),
203243
})
204244
```

0 commit comments

Comments
 (0)