Skip to content

Commit d1a5882

Browse files
authored
feat(useQuery): make query options reactive by default (#109)
* feat: make query options reactive * fix: cleanup * docs: update * fix: type * fix: increase coverage, revert test * refactor: improve types * docs: update readme
1 parent bceb408 commit d1a5882

File tree

12 files changed

+93
-34
lines changed

12 files changed

+93
-34
lines changed

README.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,13 @@ For topics not covered in vue-query docs visit https://react-query.tanstack.com/
7171
});
7272
```
7373

74-
3. If you need to update options on your query dynamically, make sure to pass it as reactive property
74+
3. If you need to update options on your query dynamically, make sure to pass them as reactive variables
7575

7676
```ts
7777
const id = ref(1);
78-
const queryKey = reactive(["todos", { id }]);
78+
const queryKey = ["todos", id];
7979
const queryFunction = () => getTodos(id);
80-
const options = reactive({
81-
enabled: false,
82-
});
80+
const enabled = ref(false);
8381

84-
const query = useQuery(queryKey, queryFunction, options);
82+
const query = useQuery(queryKey, queryFunction, { enabled });
8583
```

docs/guides/dependent-queries.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,11 @@ const enabled = computed(() => !!user.value?.id);
99

1010
// Then get the user's projects
1111
const { isIdle, data: projects } = useQuery(
12-
reactive(["projects", { userId }]),
12+
["projects", userId],
1313
() => getProjectsByUser(userId.value),
14-
reactive({
15-
// The query will not execute until the userId exists
16-
enabled,
17-
})
14+
{
15+
enabled, // The query will not execute until the userId exists
16+
}
1817
);
1918

2019
// isIdle will be `true` until `enabled` is true and the query begins to fetch.

docs/guides/parallel-queries.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const users = computed(...)
2525
const userQueries = useQueries(
2626
users.value.map(user => {
2727
return {
28-
queryKey: ['user', {userId: user.id}],
28+
queryKey: ['user', user.id],
2929
queryFn: () => fetchUserById(user.id),
3030
}
3131
})

docs/guides/placeholder-query-data.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ A good example of this would be searching the cached data from a blog post list
3939

4040
```js
4141
const result = useQuery(
42-
["blogPost", { blogPostId }],
42+
["blogPost", blogPostId],
4343
() => fetch(`/blogPosts/${blogPostId}`),
4444
{
4545
placeholderData: () => {

docs/guides/query-functions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Query keys are not just for uniquely identifying the data you are fetching, but
4848

4949
```js
5050
function useTodos(status, page) {
51-
const result = useQuery(reactive(["todos", { status, page }]), fetchTodoList);
51+
const result = useQuery(["todos", { status, page }], fetchTodoList);
5252
}
5353

5454
// Access the key, status and page variables in your query function!

docs/guides/query-keys.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,7 @@ Since query keys uniquely describe the data they are fetching, they should inclu
7070

7171
```js
7272
function useTodos(todoId) {
73-
const queryKey = reactive(["todos", { todoId }]);
73+
const queryKey = ["todos", todoId];
7474
const result = useQuery(queryKey, () => fetchTodoById(todoId.value));
7575
}
7676
```
77-
78-
!> `queryKeys` that depend on variables should be wrapped in `reactive`. Variables should be passed as an object as `refs`. This will guarantee that Vue reactivity system will work for you.

docs/guides/query-retries.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ You can configure retries both on a global level and an individual query level.
1111
import { useQuery } from "vue-query";
1212

1313
// Make a specific query retry a certain number of times
14-
const result = useQuery(["todos"], fetchTodos, {
14+
const result = useQuery("todos", fetchTodos, {
1515
retry: 10, // Will retry failed requests 10 times before displaying an error
1616
});
1717
```

src/vue/__tests__/useQuery.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,33 @@ describe("useQuery", () => {
128128
});
129129
});
130130

131+
test("should update query when an option is passed as Ref and it's changed", async () => {
132+
const enabled = ref(false);
133+
const query = useQuery("key9", simpleFetcher, { enabled });
134+
135+
await flushPromises();
136+
137+
expect(query).toMatchObject({
138+
status: { value: "idle" },
139+
data: { value: undefined },
140+
});
141+
142+
enabled.value = true;
143+
144+
await flushPromises();
145+
146+
expect(query).toMatchObject({
147+
status: { value: "loading" },
148+
data: { value: undefined },
149+
});
150+
151+
await flushPromises();
152+
153+
expect(query).toMatchObject({
154+
status: { value: "success" },
155+
});
156+
});
157+
131158
test("should properly execute dependant queries", async () => {
132159
const { data } = useQuery("dependant1", simpleFetcher);
133160

src/vue/__tests__/utils.test.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ describe("utils", () => {
4141
const options = { retry: false };
4242
const result = parseMutationArgs(options);
4343

44-
expect(result).toBe(options);
44+
expect(result).toEqual(options);
4545
});
4646

4747
test("should merge query key with options", () => {
@@ -50,7 +50,6 @@ describe("utils", () => {
5050
const expected = { ...options, mutationKey: "key" };
5151

5252
expect(result).toEqual(expected);
53-
expect(result).toBe(options);
5453
});
5554

5655
test("should merge query fn with options", () => {
@@ -59,7 +58,6 @@ describe("utils", () => {
5958
const expected = { ...options, mutationFn: successMutator };
6059

6160
expect(result).toEqual(expected);
62-
expect(result).toBe(options);
6361
});
6462

6563
test("should merge query key and fn with options", () => {
@@ -72,7 +70,6 @@ describe("utils", () => {
7270
};
7371

7472
expect(result).toEqual(expected);
75-
expect(result).toBe(options);
7673
});
7774
});
7875

@@ -81,7 +78,7 @@ describe("utils", () => {
8178
const options = { retry: false };
8279
const result = parseQueryArgs(options);
8380

84-
expect(result).toBe(options);
81+
expect(result).toStrictEqual(options);
8582
});
8683

8784
test("should merge query key with options", () => {
@@ -90,7 +87,6 @@ describe("utils", () => {
9087
const expected = { ...options, queryKey: "key" };
9188

9289
expect(result).toEqual(expected);
93-
expect(result).toBe(options);
9490
});
9591

9692
test("should merge query key and fn with options", () => {
@@ -103,7 +99,6 @@ describe("utils", () => {
10399
};
104100

105101
expect(result).toEqual(expected);
106-
expect(result).toBe(options);
107102
});
108103
});
109104

src/vue/types.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,32 @@
1+
import type { QueryKey, QueryObserverOptions } from "react-query/types/core";
2+
import { Ref } from "vue-demi";
3+
4+
export type MaybeRef<T> = Ref<T> | T;
5+
16
export type WithQueryClientKey<T> = T & { queryClientKey?: string };
7+
8+
// A Vue version of QueriesObserverOptions from "react-query/types/core"
9+
// Accept refs as options
10+
export type VueQueryObserverOptions<
11+
TQueryFnData = unknown,
12+
TError = unknown,
13+
TData = TQueryFnData,
14+
TQueryData = TQueryFnData,
15+
TQueryKey extends QueryKey = QueryKey
16+
> = {
17+
[Property in keyof QueryObserverOptions<
18+
TQueryFnData,
19+
TError,
20+
TData,
21+
TQueryData,
22+
TQueryKey
23+
>]: MaybeRef<
24+
QueryObserverOptions<
25+
TQueryFnData,
26+
TError,
27+
TData,
28+
TQueryData,
29+
TQueryKey
30+
>[Property]
31+
>;
32+
};

0 commit comments

Comments
 (0)