diff --git a/packages/mst-query/src/MstQueryHandler.ts b/packages/mst-query/src/MstQueryHandler.ts index bd08063..4531a2c 100644 --- a/packages/mst-query/src/MstQueryHandler.ts +++ b/packages/mst-query/src/MstQueryHandler.ts @@ -33,7 +33,6 @@ export type EndpointType = ( query: any ) => Promise; - type QueryHookOptions = { request?: any; staleTime?: number; @@ -41,6 +40,7 @@ type QueryHookOptions = { enabled?: boolean; isMounted?: any; isRequestEqual?: boolean; + refetchOnMount?: 'always' | 'never' | 'if-stale'; }; type NotifyOptions = { @@ -239,6 +239,14 @@ export class MstQueryHandler { return this.model.query(options); } + if (options.refetchOnMount === 'always') { + return this.model.refetch(options); + } + + if (options.refetchOnMount === 'never') { + return; + } + const now = new Date(); const cachedAt = this.cachedAt?.getTime() ?? now.getTime(); const isStale = now.getTime() - cachedAt >= (options.staleTime ?? 0); @@ -291,7 +299,7 @@ export class MstQueryHandler { queryMore(options: any = {}): Promise<() => any> { this.isFetchingMore = true; - + options.request = options.request ?? this.model.variables.request; options.pagination = options.pagination ?? this.model.variables.pagination; options.meta = options.meta ?? this.options.meta; diff --git a/packages/mst-query/src/QueryClient.ts b/packages/mst-query/src/QueryClient.ts index bba4421..fa0267e 100644 --- a/packages/mst-query/src/QueryClient.ts +++ b/packages/mst-query/src/QueryClient.ts @@ -14,6 +14,8 @@ const defaultConfig = { env: {}, queryOptions: { staleTime: 0, + refetchOnMount: 'if-stale', + refetchOnRequestChanged: 'always', }, }; diff --git a/packages/mst-query/src/hooks.ts b/packages/mst-query/src/hooks.ts index 7c6ac27..2ace032 100644 --- a/packages/mst-query/src/hooks.ts +++ b/packages/mst-query/src/hooks.ts @@ -17,6 +17,8 @@ type QueryOptions> = { request?: SnapshotIn; pagination?: SnapshotIn; onQueryMore?: (data: T['data'], self: T) => void; + refetchOnMount?: 'always' | 'never' | 'if-stale'; + refetchOnRequestChanged?: 'always' | 'never'; staleTime?: number; enabled?: boolean; initialData?: any; @@ -35,15 +37,17 @@ export function useQuery>( (options as any).request = options.request ?? EmptyRequest; (options as any).pagination = options.pagination ?? EmptyPagination; - let isRequestEqual: boolean; - if (isStateTreeNode(query.variables.request)) { - const requestType = getType(query.variables.request); - isRequestEqual = equal( - getSnapshot(requestType.create(options.request)), - getSnapshot(query.variables.request) - ); - } else { - isRequestEqual = equal(options.request, query.variables.request); + let isRequestEqual: boolean = true; + if (options.enabled && options.refetchOnRequestChanged !== 'never') { + if (isStateTreeNode(query.variables.request)) { + const requestType = getType(query.variables.request); + isRequestEqual = equal( + getSnapshot(requestType.create(options.request)), + getSnapshot(query.variables.request) + ); + } else { + isRequestEqual = equal(options.request, query.variables.request); + } } if (!observer.isMounted && !isRequestEqual) { query.setData(null); diff --git a/packages/mst-query/tests/mstQuery.test.tsx b/packages/mst-query/tests/mstQuery.test.tsx index 1c0415a..6a229cf 100644 --- a/packages/mst-query/tests/mstQuery.test.tsx +++ b/packages/mst-query/tests/mstQuery.test.tsx @@ -875,7 +875,7 @@ test('useQuery should not run when initialData is passed and staleTime is larger return
; }); render(); - + await wait(0); expect(loadingStates).toEqual([false, false]); @@ -888,3 +888,44 @@ test('useQuery should not run when initialData is passed and staleTime is larger configureMobx({ enforceActions: 'observed' }); }); + +test('refetchOnMount & refetchOnRequestChanged', async () => { + const { render, q } = setup(); + + configureMobx({ enforceActions: 'never' }); + + const getItem = vi.fn(() => Promise.resolve(itemData)); + const testApi = { + ...api, + getItem: () => getItem(), + }; + + let id = observable.box('test'); + + const Comp = observer(() => { + useQuery(q.itemQuery, { + request: { id: id.get() }, + refetchOnMount: 'always', + refetchOnRequestChanged: 'never', + staleTime: 5000, + meta: { getItem: testApi.getItem }, + }); + return
; + }); + + const { unmount } = render(); + await wait(0); + unmount(); + + render(); + await wait(0); + + expect(getItem).toHaveBeenCalledTimes(2); + + id.set('different-test'); + await wait(0); + + expect(getItem).toHaveBeenCalledTimes(2); + + configureMobx({ enforceActions: 'observed' }); +});