From 140ca1a4739e492661f584b56febda58af628c98 Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 19 Feb 2023 12:59:12 -0500 Subject: [PATCH] Revert "clear data on skip" back to its original behavior --- .../toolkit/src/query/react/buildHooks.ts | 4 +- .../src/query/tests/buildHooks.test.tsx | 51 ++++++++++++++++++- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/packages/toolkit/src/query/react/buildHooks.ts b/packages/toolkit/src/query/react/buildHooks.ts index b6822a7478..11f48f2c44 100644 --- a/packages/toolkit/src/query/react/buildHooks.ts +++ b/packages/toolkit/src/query/react/buildHooks.ts @@ -626,9 +626,7 @@ export function buildHooks({ ) lastResult = undefined } - if (queryArgs === skipToken) { - lastResult = undefined - } + // data is the last known good request result we have tracked - or if none has been tracked yet the last good result for the current args let data = currentState.isSuccess ? currentState.data : lastResult?.data if (data === undefined) data = currentState.data diff --git a/packages/toolkit/src/query/tests/buildHooks.test.tsx b/packages/toolkit/src/query/tests/buildHooks.test.tsx index 15998503d0..feabd12ee5 100644 --- a/packages/toolkit/src/query/tests/buildHooks.test.tsx +++ b/packages/toolkit/src/query/tests/buildHooks.test.tsx @@ -1,3 +1,4 @@ +import util from 'util' import * as React from 'react' import type { UseMutation, @@ -2472,7 +2473,11 @@ describe('skip behaviour', () => { await act(async () => { rerender([1, { skip: true }]) }) - expect(result.current).toEqual(uninitialized) + expect(result.current).toEqual({ + ...uninitialized, + currentData: undefined, + data: { name: 'Timmy' }, + }) await delay(1) expect(subscriptionCount('getUser(1)')).toBe(0) }) @@ -2489,6 +2494,7 @@ describe('skip behaviour', () => { expect(result.current).toEqual(uninitialized) await delay(1) + expect(subscriptionCount('getUser(1)')).toBe(0) // also no subscription on `getUser(skipToken)` or similar: expect(storeRef.store.getState().api.subscriptions).toEqual({}) @@ -2504,10 +2510,51 @@ describe('skip behaviour', () => { await act(async () => { rerender([skipToken]) }) - expect(result.current).toEqual(uninitialized) + expect(result.current).toEqual({ + ...uninitialized, + currentData: undefined, + data: { name: 'Timmy' }, + }) await delay(1) expect(subscriptionCount('getUser(1)')).toBe(0) }) + + test('skipping a previously fetched query retains the existing value as `data`, but clears `currentData`', async () => { + const { result, rerender } = renderHook( + ([arg, options]: Parameters) => + api.endpoints.getUser.useQuery(arg, options), + { + wrapper: storeRef.wrapper, + initialProps: [1], + } + ) + + await act(async () => { + await delay(1) + }) + + // Normal fulfilled result, with both `data` and `currentData` + expect(result.current).toMatchObject({ + status: QueryStatus.fulfilled, + isSuccess: true, + data: { name: 'Timmy' }, + currentData: { name: 'Timmy' }, + }) + + await act(async () => { + rerender([1, { skip: true }]) + await delay(1) + }) + + // After skipping, the query is "uninitialized", but still retains the last fetched `data` + // even though it's skipped. `currentData` is undefined, since that matches the current arg. + expect(result.current).toMatchObject({ + status: QueryStatus.uninitialized, + isSuccess: false, + data: { name: 'Timmy' }, + currentData: undefined, + }) + }) }) // type tests: