Skip to content

Commit bceb408

Browse files
authored
fix(useQueries): fix handling of queries update. Accept Ref as an argument (#105)
1 parent 0764d8f commit bceb408

File tree

3 files changed

+61
-30
lines changed

3 files changed

+61
-30
lines changed

src/vue/__tests__/test-utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ export function simpleFetcher(): Promise<string> {
1616
});
1717
}
1818

19+
export function getSimpleFetcherWithReturnData(returnData: unknown) {
20+
return () =>
21+
new Promise((resolve) => setTimeout(() => resolve(returnData), 0));
22+
}
23+
1924
export function infiniteFetcher({
2025
pageParam = 0,
2126
}: {

src/vue/__tests__/useQueries.test.ts

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { onUnmounted, reactive, set } from "vue-demi";
1+
import { onUnmounted, reactive } from "vue-demi";
22
import { setLogger } from "react-query/core";
33

44
import {
55
flushPromises,
66
rejectFetcher,
77
simpleFetcher,
8+
getSimpleFetcherWithReturnData,
89
noop,
910
} from "./test-utils";
1011
import { useQueries } from "../useQueries";
@@ -112,38 +113,51 @@ describe("useQueries", () => {
112113
});
113114

114115
test("should return state for new queries", async () => {
115-
const initialQueries = reactive([]);
116-
const queries = [
116+
const queries = reactive([
117117
{
118118
queryKey: "key31",
119-
queryFn: simpleFetcher,
119+
queryFn: getSimpleFetcherWithReturnData("value31"),
120120
},
121121
{
122122
queryKey: "key32",
123-
queryFn: simpleFetcher,
123+
queryFn: getSimpleFetcherWithReturnData("value32"),
124124
},
125-
];
126-
const queriesState = useQueries(initialQueries);
125+
{
126+
queryKey: "key33",
127+
queryFn: getSimpleFetcherWithReturnData("value33"),
128+
},
129+
]);
130+
const queriesState = useQueries(queries);
127131

128-
expect(queriesState.length).toEqual(0);
132+
await flushPromises();
129133

130-
queries.forEach((query, index) => {
131-
set(initialQueries, index, query);
132-
});
134+
queries.splice(
135+
0,
136+
queries.length,
137+
{
138+
queryKey: "key31",
139+
queryFn: getSimpleFetcherWithReturnData("value31"),
140+
},
141+
{
142+
queryKey: "key34",
143+
queryFn: getSimpleFetcherWithReturnData("value34"),
144+
}
145+
);
133146

134147
await flushPromises();
135148
await flushPromises();
136149

137150
expect(queriesState.length).toEqual(2);
138-
139151
expect(queriesState).toMatchObject([
140152
{
153+
data: "value31",
141154
status: "success",
142155
isLoading: false,
143156
isFetching: false,
144157
isStale: true,
145158
},
146159
{
160+
data: "value34",
147161
status: "success",
148162
isLoading: false,
149163
isFetching: false,

src/vue/useQueries.ts

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
22
import { QueriesObserver } from "react-query/core";
3-
import { onUnmounted, reactive, readonly, set, watch } from "vue-demi";
3+
import {
4+
onUnmounted,
5+
reactive,
6+
readonly,
7+
watch,
8+
unref,
9+
Ref,
10+
isRef,
11+
isReactive,
12+
} from "vue-demi";
413

514
import type {
615
QueryFunction,
@@ -114,33 +123,36 @@ export type UseQueriesResults<
114123
: // Fallback
115124
QueryObserverResult[];
116125

126+
type UseQueriesOptionsArg<T extends any[]> = readonly [...UseQueriesOptions<T>];
127+
117128
export function useQueries<T extends any[]>(
118-
queries: readonly [...UseQueriesOptions<T>]
129+
queries: Ref<UseQueriesOptionsArg<T>> | UseQueriesOptionsArg<T>
119130
): Readonly<UseQueriesResults<T>> {
120-
const queryClientKey = queries[0]?.queryClientKey;
131+
const queryClientKey = (unref(queries) as UseQueriesOptionsArg<T>)[0]
132+
?.queryClientKey;
121133
const queryClient = useQueryClient(queryClientKey);
122-
const defaultedQueries = queries.map((options) => {
123-
return queryClient.defaultQueryObserverOptions(options);
124-
});
134+
const defaultedQueries = (unref(queries) as UseQueriesOptionsArg<T>).map(
135+
(options) => {
136+
return queryClient.defaultQueryObserverOptions(options);
137+
}
138+
);
125139

126140
const observer = new QueriesObserver(queryClient, defaultedQueries);
127141
const state = reactive(observer.getCurrentResult());
128142
const unsubscribe = observer.subscribe((result) => {
129-
result.forEach((resultEntry, index) => {
130-
set(state, index, resultEntry);
131-
});
143+
state.splice(0, state.length, ...result);
132144
});
133145

134-
watch(
135-
() => queries,
136-
() => {
137-
const defaulted = queries.map((options) => {
138-
return queryClient.defaultQueryObserverOptions(options);
139-
});
146+
if (isRef(queries) || isReactive(queries)) {
147+
watch(queries, () => {
148+
const defaulted = (unref(queries) as UseQueriesOptionsArg<T>).map(
149+
(options) => {
150+
return queryClient.defaultQueryObserverOptions(options);
151+
}
152+
);
140153
observer.setQueries(defaulted);
141-
},
142-
{ deep: true }
143-
);
154+
});
155+
}
144156

145157
onUnmounted(() => {
146158
unsubscribe();

0 commit comments

Comments
 (0)