From bca49b930ca761531444b0723cad91cb27eb40b9 Mon Sep 17 00:00:00 2001 From: Lenz Weber Date: Wed, 1 Feb 2023 16:28:03 +0100 Subject: [PATCH] Allow `useLazyQuery` trigger fn to change `query` fixes #10496 --- .changeset/seven-cameras-kiss.md | 5 ++ .../hooks/__tests__/useLazyQuery.test.tsx | 71 +++++++++++++++++++ src/react/hooks/useLazyQuery.ts | 13 ++-- src/utilities/common/mergeOptions.ts | 2 +- 4 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 .changeset/seven-cameras-kiss.md diff --git a/.changeset/seven-cameras-kiss.md b/.changeset/seven-cameras-kiss.md new file mode 100644 index 00000000000..c4f1eb6b4ef --- /dev/null +++ b/.changeset/seven-cameras-kiss.md @@ -0,0 +1,5 @@ +--- +"@apollo/client": patch +--- + +Allow useLazyQuery trigger fn to change query diff --git a/src/react/hooks/__tests__/useLazyQuery.test.tsx b/src/react/hooks/__tests__/useLazyQuery.test.tsx index 9f5f780e090..9be6b815ec0 100644 --- a/src/react/hooks/__tests__/useLazyQuery.test.tsx +++ b/src/react/hooks/__tests__/useLazyQuery.test.tsx @@ -439,6 +439,77 @@ describe('useLazyQuery Hook', () => { }); }); + + it("changing queries", async () => { + const query1 = gql` + query { + hello + } + `; + const query2 = gql` + query { + name + } + `; + const mocks = [ + { + request: { query: query1 }, + result: { data: { hello: "world" } }, + }, + { + request: { query: query2 }, + result: { data: { name: "changed" } }, + }, + ]; + + const cache = new InMemoryCache(); + const { result } = renderHook(() => useLazyQuery(query1), { + wrapper: ({ children }) => ( + + {children} + + ), + }); + + expect(result.current[1].loading).toBe(false); + expect(result.current[1].data).toBe(undefined); + const execute = result.current[0]; + + setTimeout(() => execute()); + + await waitFor( + () => { + expect(result.current[1].loading).toBe(true); + }, + { interval: 1 } + ); + + await waitFor( + () => { + expect(result.current[1].loading).toBe(false); + }, + { interval: 1 } + ); + expect(result.current[1].data).toEqual({ hello: "world" }); + + setTimeout(() => execute({ query: query2 })); + + await waitFor( + () => { + expect(result.current[1].loading).toBe(true); + }, + { interval: 1 } + ); + + await waitFor( + () => { + expect(result.current[1].loading).toBe(false); + }, + { interval: 1 } + ); + expect(result.current[1].data).toEqual({ name: "changed" }); + }); + it('should fetch data each time the execution function is called, when using a "network-only" fetch policy', async () => { const mocks = [ { diff --git a/src/react/hooks/useLazyQuery.ts b/src/react/hooks/useLazyQuery.ts index 1493255d798..e0ffeab91dc 100644 --- a/src/react/hooks/useLazyQuery.ts +++ b/src/react/hooks/useLazyQuery.ts @@ -28,15 +28,14 @@ export function useLazyQuery ): LazyQueryResultTuple { const abortControllersRef = useRef(new Set()); - const internalState = useInternalState( - useApolloClient(options && options.client), - query, - ); const execOptionsRef = useRef>>(); - const merged = execOptionsRef.current - ? mergeOptions(options, execOptionsRef.current) - : options; + const merged = execOptionsRef.current ? mergeOptions(options, execOptionsRef.current) : options; + + const internalState = useInternalState( + useApolloClient(options && options.client), + merged?.query ?? query + ); const useQueryResult = internalState.useQuery({ ...merged, diff --git a/src/utilities/common/mergeOptions.ts b/src/utilities/common/mergeOptions.ts index 42cb3cb9451..1633a86df29 100644 --- a/src/utilities/common/mergeOptions.ts +++ b/src/utilities/common/mergeOptions.ts @@ -13,7 +13,7 @@ type OptionsUnion = | MutationOptions; export function mergeOptions< - TOptions extends OptionsUnion + TOptions extends Partial> >( defaults: TOptions | Partial | undefined, options: TOptions | Partial,