Skip to content

Commit d36595b

Browse files
authored
Fix useLazyQuery forceUpdate loop regression. (#7715)
1 parent 2b1f1f4 commit d36595b

File tree

2 files changed

+16
-20
lines changed

2 files changed

+16
-20
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## Apollo Client 3.3.11
2+
3+
### Bug fixes
4+
5+
- Fix `useLazyQuery` `forceUpdate` loop regression introduced by [#7655](https://github.com/apollographql/apollo-client/pull/7655) in version 3.3.10. <br/>
6+
[@benjamn](https://github.com/benjamn) in [#7715](https://github.com/apollographql/apollo-client/pull/7715)
7+
18
## Apollo Client 3.3.10
29

310
### Bug fixes

src/react/hooks/utils/useBaseQuery.ts

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,36 +23,31 @@ export function useBaseQuery<TData = any, TVariables = OperationVariables>(
2323
const updatedOptions = options ? { ...options, query } : { query };
2424

2525
const queryDataRef = useRef<QueryData<TData, TVariables>>();
26-
const queryData =
27-
queryDataRef.current ||
28-
new QueryData<TData, TVariables>({
26+
const queryData = queryDataRef.current || (
27+
queryDataRef.current = new QueryData<TData, TVariables>({
2928
options: updatedOptions as QueryDataOptions<TData, TVariables>,
3029
context,
3130
onNewData() {
32-
if (!queryData.ssrInitiated() && queryDataRef.current) {
31+
if (!queryData.ssrInitiated()) {
3332
// When new data is received from the `QueryData` object, we want to
3433
// force a re-render to make sure the new data is displayed. We can't
3534
// force that re-render if we're already rendering however so to be
36-
// safe we'll trigger the re-render in a microtask.
37-
Promise.resolve().then(forceUpdate);
35+
// safe we'll trigger the re-render in a microtask. In case the
36+
// component gets unmounted before this callback fires, we re-check
37+
// queryDataRef.current before calling forceUpdate().
38+
Promise.resolve().then(() => queryDataRef.current && forceUpdate());
3839
} else {
3940
// If we're rendering on the server side we can force an update at
4041
// any point.
4142
forceUpdate();
4243
}
4344
}
44-
});
45+
})
46+
);
4547

4648
queryData.setOptions(updatedOptions);
4749
queryData.context = context;
4850

49-
// SSR won't trigger the effect hook below that stores the current
50-
// `QueryData` instance for future renders, so we'll handle that here if
51-
// the current render is happening on the server side.
52-
if (queryData.ssrInitiated() && !queryDataRef.current) {
53-
queryDataRef.current = queryData;
54-
}
55-
5651
// `onError` and `onCompleted` callback functions will not always have a
5752
// stable identity, so we'll exclude them from the memoization key to
5853
// prevent `afterExecute` from being triggered un-necessarily.
@@ -76,12 +71,6 @@ export function useBaseQuery<TData = any, TVariables = OperationVariables>(
7671
: (result as QueryResult<TData, TVariables>);
7772

7873
useEffect(() => {
79-
// We only need one instance of the `QueryData` class, so we'll store it
80-
// as a ref to make it available on subsequent renders.
81-
if (!queryDataRef.current) {
82-
queryDataRef.current = queryData;
83-
}
84-
8574
return () => queryData.cleanup();
8675
}, []);
8776

0 commit comments

Comments
 (0)