MENU
Manual Cache Update
You can make changes to a cache entry directly by calling api.util.updateQueryData().
Optimistic Update. ie. reflecting changes before the server responds.
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'
const api = createApi({
baseQuery: fetchBaseQuery({
baseUrl: '/',
}),
tagTypes: ['Post'],
endpoints: (build) => ({
getPost: build.query({
query: (id) => `post/${id}`,
providesTags: ['Post'],
}),
updatePost: build.mutation({
query: ({ id, ...patch }) => ({
url: `post/${id}`,
method: 'PATCH',
body: patch,
}),
async onQueryStarted({ id, ...patch }, { dispatch, queryFulfilled }) {
const patchResult = dispatch(
api.util.updateQueryData('getPost', id, (draft) => {
Object.assign(draft, patch)
})
)
try {
await queryFulfilled
} catch {
patchResult.undo()
/**
* Alternatively, on failure you can invalidate the corresponding cache tags
* to trigger a re-fetch:
* dispatch(api.util.invalidateTags(['Post'])) <--- notice the use of another utility function
*/
}
// queryFulfilled.catch(patchResult.undo); // alternative
},
}),
}),
})
Pessimistic Update. ie. reflecting changes after the server responds.
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'
const api = createApi({
baseQuery: fetchBaseQuery({
baseUrl: '/',
}),
tagTypes: ['Post'],
endpoints: (build) => ({
getPost: build.query({
query: (id) => `post/${id}`,
providesTags: ['Post'],
}),
updatePost: build.mutation({
query: ({ id, ...patch }) => ({
url: `post/${id}`,
method: 'PATCH',
body: patch,
}),
async onQueryStarted({ id, ...patch }, { dispatch, queryFulfilled }) {
try {
const { data: updatedPost } = await queryFulfilled
const patchResult = dispatch(
api.util.updateQueryData('getPost', id, (draft) => {
Object.assign(draft, updatedPost)
})
)
} catch {}
},
}),
}),
})
General Update
import { api } from './api'
import { useAppDispatch } from './store/hooks'
function App() {
const dispatch = useAppDispatch()
function handleClick() {
/**
* This will update the cache data for the query corresponding to the `getPosts` endpoint,
* when that endpoint is used with no argument (undefined).
*/
const patchCollection = dispatch(
api.util.updateQueryData('getPosts', undefined, (draftPosts) => {
draftPosts.push({ id: 1, name: 'Teddy' })
})
)
}
return <button onClick={handleClick}>Add post to cache</button>
}
If you want to merge a JSON diff/patch array with the cached data, instead of completely replacing the old entry, you can use api.util.patchQueryData() instead.
const patchCollection = dispatch(
api.util.updateQueryData('getPosts', undefined, (draftPosts) => {
draftPosts.push({ id: 1, name: 'Teddy' })
})
)
...
dispatch(
api.util.patchQueryData('getPosts', undefined, patchCollection.inversePatches)
)
...
patchCollection.undo()