diff --git a/packages/toolkit/src/query/react/buildHooks.ts b/packages/toolkit/src/query/react/buildHooks.ts index f2c4c612f6..07b067b6d0 100644 --- a/packages/toolkit/src/query/react/buildHooks.ts +++ b/packages/toolkit/src/query/react/buildHooks.ts @@ -825,16 +825,19 @@ export function buildHooks({ const originalArgs = fixedCacheKey == null ? promise?.arg.originalArgs : undefined const reset = useCallback(() => { - if (promise) { - setPromise(undefined) - } else if (fixedCacheKey) { - dispatch( - api.internalActions.removeMutationResult({ - requestId, - fixedCacheKey, - }) - ) - } + batch(() => { + if (promise) { + setPromise(undefined) + } + if (fixedCacheKey) { + dispatch( + api.internalActions.removeMutationResult({ + requestId, + fixedCacheKey, + }) + ) + } + }) }, [dispatch, fixedCacheKey, promise, requestId]) const finalState = useMemo( () => ({ ...currentState, originalArgs, reset }), diff --git a/packages/toolkit/src/query/tests/useMutation-fixedCacheKey.test.tsx b/packages/toolkit/src/query/tests/useMutation-fixedCacheKey.test.tsx index 1fa0111e7e..c0c5290238 100644 --- a/packages/toolkit/src/query/tests/useMutation-fixedCacheKey.test.tsx +++ b/packages/toolkit/src/query/tests/useMutation-fixedCacheKey.test.tsx @@ -94,6 +94,79 @@ describe('fixedCacheKey', () => { expect(getByTestId(c2, 'data').textContent).toBe('') }) + test('resetting from the component that triggered the mutation resets for each shared result', async () => { + render( + <> + + + + + , + { wrapper: storeRef.wrapper } + ) + const c1 = screen.getByTestId('C1') + const c2 = screen.getByTestId('C2') + const c3 = screen.getByTestId('C3') + const c4 = screen.getByTestId('C4') + expect(getByTestId(c1, 'status').textContent).toBe('uninitialized') + expect(getByTestId(c2, 'status').textContent).toBe('uninitialized') + expect(getByTestId(c3, 'status').textContent).toBe('uninitialized') + expect(getByTestId(c4, 'status').textContent).toBe('uninitialized') + + // trigger with a component using the first cache key + getByTestId(c1, 'trigger').click() + + await waitFor(() => + expect(getByTestId(c1, 'status').textContent).toBe('fulfilled') + ) + + // the components with the first cache key should be affected + expect(getByTestId(c1, 'data').textContent).toBe('C1') + expect(getByTestId(c2, 'status').textContent).toBe('fulfilled') + expect(getByTestId(c2, 'data').textContent).toBe('C1') + expect(getByTestId(c2, 'status').textContent).toBe('fulfilled') + + // the components with the second cache key should be unaffected + expect(getByTestId(c3, 'data').textContent).toBe('') + expect(getByTestId(c3, 'status').textContent).toBe('uninitialized') + expect(getByTestId(c4, 'data').textContent).toBe('') + expect(getByTestId(c4, 'status').textContent).toBe('uninitialized') + + // trigger with a component using the second cache key + getByTestId(c3, 'trigger').click() + + await waitFor(() => + expect(getByTestId(c3, 'status').textContent).toBe('fulfilled') + ) + + // the components with the first cache key should be unaffected + expect(getByTestId(c1, 'data').textContent).toBe('C1') + expect(getByTestId(c2, 'status').textContent).toBe('fulfilled') + expect(getByTestId(c2, 'data').textContent).toBe('C1') + expect(getByTestId(c2, 'status').textContent).toBe('fulfilled') + + // the component with the second cache key should be affected + expect(getByTestId(c3, 'data').textContent).toBe('C3') + expect(getByTestId(c3, 'status').textContent).toBe('fulfilled') + expect(getByTestId(c4, 'data').textContent).toBe('C3') + expect(getByTestId(c4, 'status').textContent).toBe('fulfilled') + + // test reset from the component that triggered the mutation for the first cache key + getByTestId(c1, 'reset').click() + + // the components with the first cache key should be affected + expect(getByTestId(c1, 'data').textContent).toBe('') + expect(getByTestId(c1, 'status').textContent).toBe('uninitialized') + expect(getByTestId(c2, 'data').textContent).toBe('') + expect(getByTestId(c2, 'status').textContent).toBe('uninitialized') + + // the components with the second cache key should be unaffected + expect(getByTestId(c3, 'data').textContent).toBe('C3') + expect(getByTestId(c3, 'status').textContent).toBe('fulfilled') + expect(getByTestId(c4, 'data').textContent).toBe('C3') + expect(getByTestId(c4, 'status').textContent).toBe('fulfilled') + }) + test('two mutations with different `fixedCacheKey` do not influence each other', async () => { render( <>