Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Call onCompleted each time useLazyQuery executes #3497

Merged
merged 1 commit into from Sep 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions Changelog.md
Expand Up @@ -19,6 +19,8 @@
[@jet2jet](https://github.com/jet2jet) in [#3477](https://github.com/apollographql/react-apollo/pull/3477)
- Add back in the removed `ChildDataProps` and `ChildMutateProps` types. <br/>
[@hwillson](https://github.com/hwillson) in [#3495](https://github.com/apollographql/react-apollo/pull/3495)
- Make sure `onCompleted` is called each time a `useLazyQuery` based query completes, after the execution function is called. <br/>
[@hwillson](https://github.com/hwillson) in [#3497](https://github.com/apollographql/react-apollo/pull/3497)

## 3.1.0 (2019-09-06)

Expand Down
60 changes: 59 additions & 1 deletion packages/hooks/src/__tests__/useLazyQuery.test.tsx
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import { DocumentNode } from 'graphql';
import gql from 'graphql-tag';
import { MockedProvider } from '@apollo/react-testing';
Expand Down Expand Up @@ -389,4 +389,62 @@ describe('useLazyQuery Hook', () => {
});
}
);

it('should only call onCompleted once per query run', async () => {
let renderCount = 0;
let onCompletedCount = 0;
const Component = () => {
const [_, setCounter] = useState(0);
const [execute, { loading, data }] = useLazyQuery(CAR_QUERY, {
onCompleted() {
onCompletedCount += 1;
}
});

switch (renderCount) {
case 0:
expect(loading).toEqual(false);
setTimeout(() => {
execute();
});
break;
case 1:
expect(loading).toEqual(true);
break;
case 2:
expect(loading).toEqual(false);
expect(data).toEqual(CAR_RESULT_DATA);
setTimeout(() => {
execute();
});
break;
case 3:
expect(loading).toEqual(false);
expect(data).toEqual(CAR_RESULT_DATA);
// Force a render to help make sure onCompleted isn't called again
// since the query isn't re-run.
setCounter(1);
break;
case 4:
expect(loading).toEqual(false);
expect(data).toEqual(CAR_RESULT_DATA);
break;
default: // Do nothing
}

renderCount += 1;
return null;
};

render(
<MockedProvider mocks={CAR_MOCKS}>
<Component />
</MockedProvider>
);

await wait(() => {
expect(onCompletedCount).toBe(2);
expect(renderCount).toBe(5);
});
});
});
17 changes: 11 additions & 6 deletions packages/hooks/src/utils/useBaseQuery.ts
Expand Up @@ -51,12 +51,17 @@ export function useBaseQuery<TData = any, TVariables = OperationVariables>(
? (result as QueryTuple<TData, TVariables>)[1]
: (result as QueryResult<TData, TVariables>);

useEffect(() => queryData.afterExecute({ lazy }), [
queryResult.loading,
queryResult.networkStatus,
queryResult.error,
queryResult.data
]);
useEffect(
() => queryData.afterExecute({ lazy }),
lazy
? undefined
: [
queryResult.loading,
queryResult.networkStatus,
queryResult.error,
queryResult.data
]
);

useEffect(() => {
return () => queryData.cleanup();
Expand Down