Skip to content

Commit

Permalink
Merge pull request #58 from ConrabOpto/feature/refetch-on
Browse files Browse the repository at this point in the history
Add refetchOnMount & refetchOnRequestChanged
  • Loading branch information
Conny Abrahamsson authored Jan 12, 2024
2 parents 97ded72 + a2ecac7 commit 90c25b6
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 12 deletions.
12 changes: 10 additions & 2 deletions packages/mst-query/src/MstQueryHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ export type EndpointType = (
query: any
) => Promise<any>;


type QueryHookOptions = {
request?: any;
staleTime?: number;
pagination?: any;
enabled?: boolean;
isMounted?: any;
isRequestEqual?: boolean;
refetchOnMount?: 'always' | 'never' | 'if-stale';
};

type NotifyOptions = {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions packages/mst-query/src/QueryClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const defaultConfig = {
env: {},
queryOptions: {
staleTime: 0,
refetchOnMount: 'if-stale',
refetchOnRequestChanged: 'always',
},
};

Expand Down
22 changes: 13 additions & 9 deletions packages/mst-query/src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ type QueryOptions<T extends Instance<QueryReturnType>> = {
request?: SnapshotIn<T['variables']['request']>;
pagination?: SnapshotIn<T['variables']['pagination']>;
onQueryMore?: (data: T['data'], self: T) => void;
refetchOnMount?: 'always' | 'never' | 'if-stale';
refetchOnRequestChanged?: 'always' | 'never';
staleTime?: number;
enabled?: boolean;
initialData?: any;
Expand All @@ -35,15 +37,17 @@ export function useQuery<T extends Instance<QueryReturnType>>(
(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);
Expand Down
43 changes: 42 additions & 1 deletion packages/mst-query/tests/mstQuery.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,7 @@ test('useQuery should not run when initialData is passed and staleTime is larger
return <div></div>;
});
render(<Comp />);

await wait(0);

expect(loadingStates).toEqual([false, false]);
Expand All @@ -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 <div></div>;
});

const { unmount } = render(<Comp />);
await wait(0);
unmount();

render(<Comp />);
await wait(0);

expect(getItem).toHaveBeenCalledTimes(2);

id.set('different-test');
await wait(0);

expect(getItem).toHaveBeenCalledTimes(2);

configureMobx({ enforceActions: 'observed' });
});

0 comments on commit 90c25b6

Please sign in to comment.