diff --git a/packages/toolkit/src/query/core/buildSlice.ts b/packages/toolkit/src/query/core/buildSlice.ts index 41b75c94ce..195c0863e3 100644 --- a/packages/toolkit/src/query/core/buildSlice.ts +++ b/packages/toolkit/src/query/core/buildSlice.ts @@ -136,7 +136,8 @@ export function buildSlice({ extraReducers(builder) { builder .addCase(queryThunk.pending, (draft, { meta, meta: { arg } }) => { - if (arg.subscribe) { + const upserting = isUpsertQuery(arg) + if (arg.subscribe || upserting) { // only initialize substate if we want to subscribe to it draft[arg.queryCacheKey] ??= { status: QueryStatus.uninitialized, @@ -148,7 +149,7 @@ export function buildSlice({ substate.status = QueryStatus.pending substate.requestId = - isUpsertQuery(arg) && substate.requestId + upserting && substate.requestId ? // for `upsertQuery` **updates**, keep the current `requestId` substate.requestId : // for normal queries or `upsertQuery` **inserts** always update the `requestId` diff --git a/packages/toolkit/src/query/tests/optimisticUpserts.test.tsx b/packages/toolkit/src/query/tests/optimisticUpserts.test.tsx index c500ba0986..5ca0fd050e 100644 --- a/packages/toolkit/src/query/tests/optimisticUpserts.test.tsx +++ b/packages/toolkit/src/query/tests/optimisticUpserts.test.tsx @@ -98,6 +98,41 @@ describe('basic lifecycle', () => { onSuccess.mockReset() }) + test('Does basic inserts and upserts', async () => { + const newPost: Post = { + id: '3', + contents: 'Inserted content', + title: 'Inserted title', + } + const insertPromise = storeRef.store.dispatch( + api.util.upsertQueryData('post', newPost.id, newPost) + ) + + await insertPromise + + const selectPost3 = api.endpoints.post.select(newPost.id) + const insertedPostEntry = selectPost3(storeRef.store.getState()) + expect(insertedPostEntry.isSuccess).toBe(true) + expect(insertedPostEntry.data).toEqual(newPost) + + const updatedPost: Post = { + id: '3', + contents: 'Updated content', + title: 'Updated title', + } + + const updatePromise = storeRef.store.dispatch( + api.util.upsertQueryData('post', updatedPost.id, updatedPost) + ) + + await updatePromise + + const updatedPostEntry = selectPost3(storeRef.store.getState()) + + expect(updatedPostEntry.isSuccess).toBe(true) + expect(updatedPostEntry.data).toEqual(updatedPost) + }) + test('success', async () => { const { result } = renderHook( () => extendedApi.endpoints.test.useMutation(),