From 1aaf5205380e7c9d220fbc57b7f5b14d730fa1b0 Mon Sep 17 00:00:00 2001 From: Kim Date: Tue, 15 Oct 2024 22:07:31 +0200 Subject: [PATCH] Fix useQuery issue with initialData #75 --- packages/mst-query/src/MstQueryHandler.ts | 26 +++++++++++-------- packages/mst-query/tests/mstQuery.test.tsx | 30 +++++++++++++++++++--- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/packages/mst-query/src/MstQueryHandler.ts b/packages/mst-query/src/MstQueryHandler.ts index 7431026..73a8b8f 100644 --- a/packages/mst-query/src/MstQueryHandler.ts +++ b/packages/mst-query/src/MstQueryHandler.ts @@ -81,18 +81,20 @@ export class QueryObserver { if (this.isQuery) { options.isMounted = this.isMounted; - if (!options.isRequestEqual) { - this.query.setData(null); - } - - if (!this.isMounted && options.initialData) { - const initialDataUpdatedAt = options.initialDataUpdatedAt ?? new Date(); - if (!isDataStale(initialDataUpdatedAt, options.staleTime)) { + if (options.initialData) { + const isStale = isDataStale(options.initialDataUpdatedAt, options.staleTime); + if (!isStale) { this.query.__MstQueryHandler.hydrate(options); + } else { + this.query.__MstQueryHandler.queryWhenChanged(options); + } + } else { + if (!options.isRequestEqual) { + this.query.setData(null); } - } - this.query.__MstQueryHandler.queryWhenChanged(options); + this.query.__MstQueryHandler.queryWhenChanged(options); + } } if (!this.isMounted) { @@ -546,6 +548,8 @@ export class MstQueryHandler { } } -function isDataStale(cachedAt: number, staleTime: number = 0) { - return Date.now() - cachedAt >= staleTime; +function isDataStale(cachedAt?: number, staleTime: number = 0) { + const now = Date.now(); + const cachedTime = cachedAt ?? now; + return now - cachedTime >= staleTime; } diff --git a/packages/mst-query/tests/mstQuery.test.tsx b/packages/mst-query/tests/mstQuery.test.tsx index 119cfc6..f116953 100644 --- a/packages/mst-query/tests/mstQuery.test.tsx +++ b/packages/mst-query/tests/mstQuery.test.tsx @@ -854,31 +854,53 @@ test('useQuery should not run when initialData is passed and staleTime is larger let id = observable.box('test'); const initialData = await api.getItem({ request: { id: id.get() } }); - const loadingStates: boolean[] = []; + let loadingStates: boolean[] = []; + const isLoadingReaction = reaction( + () => q.itemQuery.isLoading, + (isLoading) => { + loadingStates.push(isLoading); + } + ); + + let dataStates: any[] = []; + const dataReaction = reaction( + () => q.itemQuery.data, + (data: any) => { + dataStates.push(data ? data.id : null); + } + ); + const Comp = observer(() => { const { query, isLoading } = useQuery(q.itemQuery, { initialData, request: { id: id.get() }, staleTime: 10, }); - loadingStates.push(isLoading); return
; }); render(); await wait(0); - expect(loadingStates).toEqual([false, false]); + expect(loadingStates).toEqual([]); + expect(dataStates).toEqual(["test"]); expect(q.itemQuery.data?.id).toBe('test'); id.set('different-test'); await wait(0); - expect(q.itemQuery.data?.id).toBe('different-test'); + + expect(q.itemQuery.data?.id).toBe('test'); expect(q.itemQuery.variables.request?.id).toBe('different-test'); + expect(loadingStates).toEqual([]); + expect(dataStates).toEqual(["test"]); + + isLoadingReaction(); + dataReaction(); configureMobx({ enforceActions: 'observed' }); }); + test('useQuery should run when initialData is passed and initialDataUpdatedAt is older than staleTime', async () => { const { render, q } = setup();