Skip to content

Commit 76f3314

Browse files
committed
feat: useIsMutating hook
1 parent 7999644 commit 76f3314

File tree

6 files changed

+112
-4
lines changed

6 files changed

+112
-4
lines changed

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"homepage": "https://github.com/DamianOsipiuk/vue-query#readme",
3434
"dependencies": {
3535
"match-sorter": "^6.3.0",
36-
"react-query": "^3.12.2",
36+
"react-query": "^3.13.9",
3737
"vue-demi": "^0.7.4"
3838
},
3939
"peerDependencies": {

src/devtools/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* istanbul ignore file */
2+
13
export { default as VueQueryDevTools } from "./Devtools.vue";
24
export { default as VueQueryDevToolsPanel } from "./DevtoolsPanel.vue";
35
export { VUE_QUERY_DEVTOOLS_THEME } from "./useTheme";

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* istanbul ignore file */
2+
13
export { QueryClient } from "react-query/core";
24

35
export { useQueryClient, VUE_QUERY_CLIENT } from "./useQueryClient";
@@ -7,3 +9,4 @@ export { useQueries } from "./useQueries";
79
export { useInfiniteQuery } from "./useInfiniteQuery";
810
export { useMutation } from "./useMutation";
911
export { useIsFetching } from "./useIsFetching";
12+
export { useIsMutating } from "./useIsMutating";

src/useIsMutating.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { onUnmounted, Ref, ref } from "vue-demi";
2+
import { MutationFilters } from "react-query/types/core/utils";
3+
import { useQueryClient } from "./useQueryClient";
4+
5+
export function useIsMutating(filters?: MutationFilters): Ref<number> {
6+
const queryClient = useQueryClient();
7+
8+
const isMutating = ref(queryClient.isMutating(filters));
9+
10+
const unsubscribe = queryClient.getMutationCache().subscribe(() => {
11+
isMutating.value = queryClient.isMutating(filters);
12+
});
13+
14+
onUnmounted(() => {
15+
unsubscribe();
16+
});
17+
18+
return isMutating;
19+
}

tests/useIsMutating.test.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { onUnmounted } from "vue-demi";
2+
import { QueryClient, setLogger } from "react-query/core";
3+
import { useMutation } from "../src/useMutation";
4+
import { useIsMutating } from "../src/useIsMutating";
5+
import { flushPromises, simpleFetcher, noop, successMutator } from "./utils";
6+
7+
jest.mock("vue", () => {
8+
const vue = jest.requireActual("vue");
9+
return {
10+
...vue,
11+
onUnmounted: jest.fn(),
12+
};
13+
});
14+
15+
jest.mock("../src/useQueryClient", () => {
16+
const queryClient = new QueryClient();
17+
return {
18+
useQueryClient: jest.fn(() => queryClient),
19+
};
20+
});
21+
22+
jest.mock("../src/useBaseQuery", () => {
23+
const { useBaseQuery: originImpl } = jest.requireActual(
24+
"../src/useBaseQuery"
25+
);
26+
return {
27+
useBaseQuery: jest.fn(originImpl),
28+
};
29+
});
30+
31+
describe("useIsMutating", () => {
32+
beforeAll(() => {
33+
setLogger({ log: noop, warn: noop, error: noop });
34+
});
35+
36+
beforeEach(() => {
37+
jest.clearAllMocks();
38+
});
39+
40+
test("should properly return isMutating state", async () => {
41+
const mutation = useMutation((params: string) => successMutator(params));
42+
const mutation2 = useMutation((params: string) => successMutator(params));
43+
const isMutating = useIsMutating();
44+
45+
expect(isMutating.value).toStrictEqual(0);
46+
47+
mutation.mutateAsync("a");
48+
mutation2.mutateAsync("b");
49+
50+
await flushPromises();
51+
52+
expect(isMutating.value).toStrictEqual(2);
53+
54+
await flushPromises();
55+
56+
expect(isMutating.value).toStrictEqual(0);
57+
});
58+
59+
test("should stop listening to changes on onUnmount", async () => {
60+
const onUnmountedMock = onUnmounted as jest.MockedFunction<
61+
typeof onUnmounted
62+
>;
63+
onUnmountedMock.mockImplementation((fn) => fn());
64+
65+
const mutation = useMutation((params: string) => successMutator(params));
66+
const mutation2 = useMutation((params: string) => successMutator(params));
67+
const isMutating = useIsMutating();
68+
69+
expect(isMutating.value).toStrictEqual(0);
70+
71+
mutation.mutateAsync("a");
72+
mutation2.mutateAsync("b");
73+
74+
await flushPromises();
75+
76+
expect(isMutating.value).toStrictEqual(0);
77+
78+
await flushPromises();
79+
80+
expect(isMutating.value).toStrictEqual(0);
81+
82+
onUnmountedMock.mockReset();
83+
});
84+
});

0 commit comments

Comments
 (0)