Skip to content

Commit d567ef3

Browse files
committed
Document upsertQueryData
1 parent 5ff666f commit d567ef3

File tree

3 files changed

+73
-10
lines changed

3 files changed

+73
-10
lines changed

docs/rtk-query/api/created-api/api-slice-utils.mdx

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@ The API slice object includes various utilities that can be used for cache manag
1313
such as implementing [optimistic updates](../../usage/manual-cache-updates.mdx#optimistic-updates),
1414
as well implementing [server side rendering](../../usage/server-side-rendering.mdx).
1515

16-
These are included in a `util` field inside the slice object.
16+
These are included as `api.util` inside the API object.
17+
18+
:::info
19+
20+
Some of the TS types on this page are pseudocode to illustrate intent, as the actual internal types are fairly complex.
21+
22+
:::
1723

1824
### `updateQueryData`
1925

@@ -48,8 +54,7 @@ The thunk returns an object containing `{patches: Patch[], inversePatches: Patch
4854

4955
This is typically used as the first step in implementing optimistic updates. The generated `inversePatches` can be used to revert the updates by calling `dispatch(patchQueryData(endpointName, args, inversePatches))`. Alternatively, the `undo` method can be called directly to achieve the same effect.
5056

51-
Note that the first two arguments (`endpointName` and `args`) are used to determine which existing
52-
cache entry to update. If no existing cache entry is found, the `updateRecipe` callback will not run.
57+
Note that the first two arguments (`endpointName` and `args`) are used to determine which existing cache entry to update. If no existing cache entry is found, the `updateRecipe` callback will not run.
5358

5459
#### Example 1
5560

@@ -105,6 +110,43 @@ dispatch(api.endpoints.getPostById.initiate(1))
105110
dispatch(api.endpoints.getPostById.initiate(1, { ...options }))
106111
```
107112

113+
### `upsertQueryData`
114+
115+
#### Signature
116+
117+
```ts no-transpile
118+
const upsertQueryData = <T>(
119+
endpointName: string,
120+
args: any,
121+
newEntryData: T
122+
) => ThunkAction<Promise<CacheEntry<T>>, PartialState, any, AnyAction>;
123+
```
124+
125+
- **Parameters**
126+
- `endpointName`: a string matching an existing endpoint name
127+
- `args`: an argument matching that used for a previous query call, used to determine which cached dataset needs to be updated
128+
- `newEntryValue`: the value to be written into the corresponding cache entry's `data` field
129+
130+
#### Description
131+
132+
A Redux thunk action creator that, when dispatched, acts as an artificial API request to upsert a value into the cache.
133+
134+
The thunk action creator accepts three arguments: the name of the endpoint we are updating (such as `'getPost'`), the appropriate query arg values to construct the desired cache key, and the data to upsert.
135+
136+
If no cache entry for that cache key exists, a cache entry will be created and the data added. If a cache entry already exists, this will _overwrite_ the existing cache entry data.
137+
138+
The thunk executes _asynchronously_, and returns a promise that resolves when the store has been updated.
139+
140+
If dispatched while an actual request is in progress, both the upsert and request will be handled as soon as they resolve, resulting in a "last result wins" update behavior.
141+
142+
#### Example
143+
144+
```ts no-transpile
145+
await dispatch(
146+
api.util.upsertQueryData('getPost', { id: 1 }, { id: 1, text: 'Hello!' })
147+
)
148+
```
149+
108150
### `patchQueryData`
109151

110152
#### Signature
@@ -124,9 +166,9 @@ const patchQueryData = (
124166

125167
#### Description
126168

127-
A Redux thunk action creator that applies a JSON diff/patch array to the cached data for a given query result. This immediately updates the Redux state with those changes.
169+
A Redux thunk action creator that, when dispatched, applies a JSON diff/patch array to the cached data for a given query result. This immediately updates the Redux state with those changes.
128170

129-
The thunk action creator accepts three arguments: the name of the endpoint we are updating (such as `'getPost'`), any relevant query arguments, and a JSON diff/patch array as produced by Immer's `produceWithPatches`.
171+
The thunk action creator accepts three arguments: the name of the endpoint we are updating (such as `'getPost'`), the appropriate query arg values to construct the desired cache key, and a JSON diff/patch array as produced by Immer's `produceWithPatches`.
130172

131173
This is typically used as the second step in implementing optimistic updates. If a request fails, the optimistically-applied changes can be reverted by dispatching `patchQueryData` with the `inversePatches` that were generated by `updateQueryData` earlier.
132174

packages/toolkit/src/query/core/module.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ declare module '../apiTypes' {
229229
/**
230230
* A Redux thunk that can be used to manually trigger pre-fetching of data.
231231
*
232-
* The thunk accepts three arguments: the name of the endpoint we are updating (such as `'getPost'`), any relevant query arguments, and a set of options used to determine if the data actually should be re-fetched based on cache staleness.
232+
* The thunk accepts three arguments: the name of the endpoint we are updating (such as `'getPost'`), the appropriate query arg values to construct the desired cache key, and a set of options used to determine if the data actually should be re-fetched based on cache staleness.
233233
*
234234
* React Hooks users will most likely never need to use this directly, as the `usePrefetch` hook will dispatch this thunk internally as needed when you call the prefetching function supplied by the hook.
235235
*
@@ -247,12 +247,14 @@ declare module '../apiTypes' {
247247
/**
248248
* A Redux thunk action creator that, when dispatched, creates and applies a set of JSON diff/patch objects to the current state. This immediately updates the Redux state with those changes.
249249
*
250-
* The thunk action creator accepts three arguments: the name of the endpoint we are updating (such as `'getPost'`), any relevant query arguments, and a callback function. The callback receives an Immer-wrapped `draft` of the current state, and may modify the draft to match the expected results after the mutation completes successfully.
250+
* The thunk action creator accepts three arguments: the name of the endpoint we are updating (such as `'getPost'`), the appropriate query arg values to construct the desired cache key, and an `updateRecipe` callback function. The callback receives an Immer-wrapped `draft` of the current state, and may modify the draft to match the expected results after the mutation completes successfully.
251251
*
252-
* The thunk returns an object containing `{patches: Patch[], inversePatches: Patch[], undo: () => void}`. The `patches` and `inversePatches` are generated using Immer's [`produceWithPatches` method](https://immerjs.github.io/immer/patches).
252+
* The thunk executes _synchronously_, and returns an object containing `{patches: Patch[], inversePatches: Patch[], undo: () => void}`. The `patches` and `inversePatches` are generated using Immer's [`produceWithPatches` method](https://immerjs.github.io/immer/patches).
253253
*
254254
* This is typically used as the first step in implementing optimistic updates. The generated `inversePatches` can be used to revert the updates by calling `dispatch(patchQueryData(endpointName, args, inversePatches))`. Alternatively, the `undo` method can be called directly to achieve the same effect.
255255
*
256+
* Note that the first two arguments (`endpointName` and `args`) are used to determine which existing cache entry to update. If no existing cache entry is found, the `updateRecipe` callback will not run.
257+
*
256258
* @example
257259
*
258260
* ```ts
@@ -272,14 +274,33 @@ declare module '../apiTypes' {
272274
Definitions,
273275
RootState<Definitions, string, ReducerPath>
274276
>
277+
/**
278+
* A Redux thunk action creator that, when dispatched, acts as an artificial API request to upsert a value into the cache.
279+
*
280+
* The thunk action creator accepts three arguments: the name of the endpoint we are updating (such as `'getPost'`), the appropriate query arg values to construct the desired cache key, and the data to upsert.
281+
*
282+
* If no cache entry for that cache key exists, a cache entry will be created and the data added. If a cache entry already exists, this will _overwrite_ the existing cache entry data.
283+
*
284+
* The thunk executes _asynchronously_, and returns a promise that resolves when the store has been updated.
285+
*
286+
* If dispatched while an actual request is in progress, both the upsert and request will be handled as soon as they resolve, resulting in a "last result wins" update behavior.
287+
*
288+
* @example
289+
*
290+
* ```ts
291+
* await dispatch(
292+
* api.util.upsertQueryData('getPost', {id: 1}, {id: 1, text: "Hello!"})
293+
* )
294+
* ```
295+
*/
275296
upsertQueryData: UpsertQueryDataThunk<
276297
Definitions,
277298
RootState<Definitions, string, ReducerPath>
278299
>
279300
/**
280301
* A Redux thunk that applies a JSON diff/patch array to the cached data for a given query result. This immediately updates the Redux state with those changes.
281302
*
282-
* The thunk accepts three arguments: the name of the endpoint we are updating (such as `'getPost'`), any relevant query arguments, and a JSON diff/patch array as produced by Immer's `produceWithPatches`.
303+
* The thunk accepts three arguments: the name of the endpoint we are updating (such as `'getPost'`), the appropriate query arg values to construct the desired cache key, and a JSON diff/patch array as produced by Immer's `produceWithPatches`.
283304
*
284305
* This is typically used as the second step in implementing optimistic updates. If a request fails, the optimistically-applied changes can be reverted by dispatching `patchQueryData` with the `inversePatches` that were generated by `updateQueryData` earlier.
285306
*

packages/toolkit/src/query/tests/optimisticUpserts.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ describe('basic lifecycle', () => {
182182
})
183183

184184
describe('upsertQueryData', () => {
185-
test('updates cache values, can apply inverse patch', async () => {
185+
test('inserts cache entry', async () => {
186186
baseQuery
187187
.mockResolvedValueOnce({
188188
id: '3',

0 commit comments

Comments
 (0)