diff --git a/.changeset/eight-webs-buy.md b/.changeset/eight-webs-buy.md new file mode 100644 index 0000000000..a49c41b912 --- /dev/null +++ b/.changeset/eight-webs-buy.md @@ -0,0 +1,18 @@ +--- +'@tanstack/query-broadcast-client-experimental': patch +'@tanstack/query-async-storage-persister': patch +'@tanstack/angular-query-persist-client': patch +'@tanstack/query-sync-storage-persister': patch +'@tanstack/svelte-query-persist-client': patch +'@tanstack/angular-query-experimental': patch +'@tanstack/react-query-persist-client': patch +'@tanstack/solid-query-persist-client': patch +'@tanstack/query-persist-client-core': patch +'@tanstack/svelte-query': patch +'@tanstack/react-query': patch +'@tanstack/solid-query': patch +'@tanstack/query-core': patch +'@tanstack/vue-query': patch +--- + +Fixed isFetchedAfterMount in cases where initialData is applied diff --git a/packages/query-core/src/__tests__/query.test.tsx b/packages/query-core/src/__tests__/query.test.tsx index f11bf173d3..a33bf75cfc 100644 --- a/packages/query-core/src/__tests__/query.test.tsx +++ b/packages/query-core/src/__tests__/query.test.tsx @@ -1304,4 +1304,47 @@ describe('query', () => { data: 'data1', }) }) + + test('should not increment dataUpdateCount when setting initialData on prefetched query', async () => { + const key = queryKey() + const queryFn = vi.fn().mockImplementation(() => 'fetched-data') + + // First prefetch the query (creates query without data) + queryClient.prefetchQuery({ + queryKey: key, + queryFn, + }) + + const query = queryCache.find({ queryKey: key })! + expect(query.state.data).toBeUndefined() + expect(query.state.dataUpdateCount).toBe(0) + + // Now create an observer with initialData + const observer = new QueryObserver(queryClient, { + queryKey: key, + queryFn, + initialData: 'initial-data', + }) + + // The query should now have the initial data but dataUpdateCount should still be 0 + // since this was not fetched data but initial data + expect(query.state.data).toBe('initial-data') + expect(query.state.dataUpdateCount).toBe(0) + + // Get the initial state as captured by the observer + const result = observer.getCurrentResult() + expect(result.data).toBe('initial-data') + expect(result.isFetchedAfterMount).toBe(false) // This should be false since no actual fetch occurred + + // Now trigger a refetch through the observer to simulate real-world usage + await observer.refetch() + + // After actual fetch, dataUpdateCount should increment + expect(query.state.dataUpdateCount).toBe(1) + expect(query.state.data).toBe('fetched-data') + + // And isFetchedAfterMount should now be true + const updatedResult = observer.getCurrentResult() + expect(updatedResult.isFetchedAfterMount).toBe(true) + }) }) diff --git a/packages/query-core/src/query.ts b/packages/query-core/src/query.ts index a34c8630dc..e033846601 100644 --- a/packages/query-core/src/query.ts +++ b/packages/query-core/src/query.ts @@ -210,9 +210,11 @@ export class Query< if (this.state && this.state.data === undefined) { const defaultState = getDefaultState(this.options) if (defaultState.data !== undefined) { - this.setData(defaultState.data, { - updatedAt: defaultState.dataUpdatedAt, - manual: true, + this.setState({ + data: defaultState.data, + dataUpdatedAt: defaultState.dataUpdatedAt, + status: 'success', + error: null, }) this.#initialState = defaultState }