diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5f14898b674..7eab5e2a734 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,9 @@
- Guarantee `Concast` cleanup without `Observable cancelled prematurely` rejection, potentially solving long-standing issues involving that error.
[@benjamn](https://github.com/benjamn) in [#9701](https://github.com/apollographql/apollo-client/pull/9701)
+- Ensure `useSubscription` subscriptions are properly restarted after unmounting/remounting by React 18 in ``.
+ [@benjamn](https://github.com/benjamn) in [#9707](https://github.com/apollographql/apollo-client/pull/9707)
+
### Improvements
- Internalize `useSyncExternalStore` shim, for more control than `use-sync-external-store` provides, fixing some React Native issues.
diff --git a/package.json b/package.json
index ff9b3fd119b..8fae2f6c817 100644
--- a/package.json
+++ b/package.json
@@ -56,7 +56,7 @@
{
"name": "apollo-client",
"path": "./dist/apollo-client.min.cjs",
- "maxSize": "29.45kB"
+ "maxSize": "29.5kB"
}
],
"engines": {
diff --git a/src/react/hooks/useSubscription.ts b/src/react/hooks/useSubscription.ts
index f1335048b53..7207657c64e 100644
--- a/src/react/hooks/useSubscription.ts
+++ b/src/react/hooks/useSubscription.ts
@@ -38,6 +38,13 @@ export function useSubscription(
});
});
+ const canResetObservableRef = useRef(false);
+ useEffect(() => {
+ return () => {
+ canResetObservableRef.current = true;
+ };
+ }, []);
+
const ref = useRef({ client, subscription, options });
useEffect(() => {
let shouldResubscribe = options?.shouldResubscribe;
@@ -46,7 +53,7 @@ export function useSubscription(
}
if (options?.skip) {
- if (!options?.skip !== !ref.current.options?.skip) {
+ if (!options?.skip !== !ref.current.options?.skip || canResetObservableRef.current) {
setResult({
loading: false,
data: void 0,
@@ -54,15 +61,16 @@ export function useSubscription(
variables: options?.variables,
});
setObservable(null);
+ canResetObservableRef.current = false;
}
} else if (
- shouldResubscribe !== false && (
- client !== ref.current.client ||
- subscription !== ref.current.subscription ||
- options?.fetchPolicy !== ref.current.options?.fetchPolicy ||
- !options?.skip !== !ref.current.options?.skip ||
- !equal(options?.variables, ref.current.options?.variables)
- )
+ (shouldResubscribe !== false &&
+ (client !== ref.current.client ||
+ subscription !== ref.current.subscription ||
+ options?.fetchPolicy !== ref.current.options?.fetchPolicy ||
+ !options?.skip !== !ref.current.options?.skip ||
+ !equal(options?.variables, ref.current.options?.variables))) ||
+ canResetObservableRef.current
) {
setResult({
loading: true,
@@ -76,10 +84,11 @@ export function useSubscription(
fetchPolicy: options?.fetchPolicy,
context: options?.context,
}));
+ canResetObservableRef.current = false;
}
Object.assign(ref.current, { client, subscription, options });
- }, [client, subscription, options]);
+ }, [client, subscription, options, canResetObservableRef.current]);
useEffect(() => {
if (!observable) {