Skip to content

Commit

Permalink
Fix useQuery issue with initialData #75
Browse files Browse the repository at this point in the history
  • Loading branch information
k-ode committed Oct 15, 2024
1 parent 7e08e53 commit 1aaf520
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 15 deletions.
26 changes: 15 additions & 11 deletions packages/mst-query/src/MstQueryHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}
30 changes: 26 additions & 4 deletions packages/mst-query/tests/mstQuery.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <div></div>;
});
render(<Comp />);

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();

Expand Down

0 comments on commit 1aaf520

Please sign in to comment.