Skip to content

Commit 58c55ff

Browse files
authoredSep 24, 2023
Merge pull request #3482 from KMNowak/docs/manual_cache_inputs
2 parents d14814f + c40e9d8 commit 58c55ff

File tree

1 file changed

+48
-27
lines changed

1 file changed

+48
-27
lines changed
 

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

+48-27
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
 
@@ -12,36 +12,38 @@ description: 'RTK Query > Usage > Manual Cache Updates: Updating cached data man
1212

1313
## Overview
1414

15-
For most cases, in order to receive up to date data after a triggering a change in the backend,
16-
you can take advantage of `cache tag invalidation` to perform
17-
[automated re-fetching](./automated-refetching), which will cause a query to re-fetch its data
18-
when it has been told that a mutation has occurred which would cause its data to become out of date.
19-
In most cases, we recommend using `automated re-fetching` as a preference over `manual cache updates`,
20-
unless you encounter the need to do so.
15+
For most cases, in order to receive up to date data after a triggering a change in the backend, you can take advantage of cache tag invalidation to perform [automated re-fetching](./automated-refetching). This will cause a query to re-fetch its data when it has been told that a mutation has occurred which would cause its data to become out of date.
2116

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.
17+
We recommend using automated re-fetching as a preference over manual cache updates in most situations.
2618

27-
Anywhere you have access to the `dispatch` method for the store instance, you can dispatch the
28-
result of calling `updateQueryData` in order to update the cache data for a query endpoint,
29-
if the corresponding cache entry exists.
19+
However, there _are_ use cases when manual cache updates are necessary, such as "optimistic" or "pessimistic" updates, or modifying data as part of cache entry lifecycles.
3020

31-
Use cases for manual cache updates include:
21+
RTK Query exports thunks for these use cases, attached to `api.utils`:
3222

23+
- [`updateQueryData`](../api/created-api/api-slice-utils.mdx#updatequerydata): updates an already existing cache entry
24+
- [`upsertQueryData`](../api/created-api/api-slice-utils.mdx#upsertquerydata): creates or replaces cache entries
25+
26+
Since these are thunks, you can dispatch them anywhere you have access to `dispatch`.
27+
28+
### Updating existing cache entries
29+
30+
For updates of existing cache entries, use [`updateQueryData`](../api/created-api/api-slice-utils.mdx#updatequerydata).
31+
32+
`updateQueryData` is strictly intended to perform _updates_ to existing cache entries, not create new entries. If an `updateQueryData` thunk action is dispatched and the `endpointName` + `args` combination that does not match any existing cache entry, the provided `recipe` callback will not be called, and no `patches` or `inversePatches` will be returned.
33+
34+
Use cases for manual update of cache entries:
3335
- 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-
`updateQueryData` is strictly intended to perform _updates_ to existing cache entries,
41-
not create new entries. If an `updateQueryData` thunk action is dispatched that corresponds to
42-
no existing cache entry for the provided `endpointName` + `args` combination, the provided `recipe`
43-
will not be called, and no `patches` or `inversePatches` will be returned.
44-
:::
36+
- After a mutation, updating a single item in a large list of items that is already cached, rather than re-fetching the whole list
37+
- Debouncing a large number of mutations with immediate feedback as though they are being applied, followed by a single request sent to the server to update the debounced attempts
38+
39+
### Creating new cache entries or replacing existing ones
40+
41+
To create or replace existing cache entries, use [`upsertQueryData`](../api/created-api/api-slice-utils.mdx#upsertquerydata).
42+
43+
`upsertQueryData` is intended to perform _replacements_ to existing cache entries or _creation_ of new ones. Since `upsertQueryData` does not have access to the previous state of the cache entry, the update may be performed only as a replacement. In comparison, `updateQueryData` allows patching of the existing cache entry, but cannot create a new one.
44+
45+
46+
One example use case is [pessimistic updates](../usage/manual-cache-updates.mdx#pessimistic-updates). If the client makes an API call to create a `Post`, the backend could return its complete data including the `id`. Then we can use `upsertQueryData` to create a new cache entry for the `getPostById(id)` query, preventing an extra fetch to retrieve the item later.
4547

4648
## Recipes
4749

@@ -57,7 +59,7 @@ The core concepts for an optimistic update are:
5759
- when you start a query or mutation, `onQueryStarted` will be executed
5860
- you manually update the cached data by dispatching `api.util.updateQueryData` within `onQueryStarted`
5961
- 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,
62+
- you roll it back via the `.undo` property of the object you got back from the earlier dispatch,
6163
OR
6264
- you invalidate the cache data via `api.util.invalidateTags` to trigger a full re-fetch of the data
6365

@@ -158,6 +160,8 @@ The core concepts for a pessimistic update are:
158160
server in the `data` property
159161
- you manually update the cached data by dispatching `api.util.updateQueryData` within
160162
`onQueryStarted`, using the data in the response from the server for your draft updates
163+
- you manually create a new cache entry by dispatching `api.util.upsertQueryData` within `onQueryStarted`,
164+
using the complete Post object returned by backend.
161165

162166
```ts title="Pessimistic update mutation example (async await)"
163167
// file: types.ts noEmit
@@ -199,6 +203,23 @@ const api = createApi({
199203
},
200204
// highlight-end
201205
}),
206+
createPost: build.mutation<Post, Pick<Post, 'id'> & Partial<Post>>({
207+
query: ({ id, ...body }) => ({
208+
url: `post/${id}`,
209+
method: 'POST',
210+
body,
211+
}),
212+
// highlight-start
213+
async onQueryStarted({ id }, { dispatch, queryFulfilled }) {
214+
try {
215+
const { data: createdPost } = await queryFulfilled
216+
const patchResult = dispatch(
217+
api.util.upsertQueryData('getPost', id, createdPost)
218+
)
219+
} catch {}
220+
},
221+
// highlight-end
222+
}),
202223
}),
203224
})
204225
```

0 commit comments

Comments
 (0)
Please sign in to comment.