Skip to content

Commit 4571e1a

Browse files
authored
Merge pull request #9707 from kazekyo/fix_usesubscription_in_strict_mode
Fix useSubscription bug in React v18 <StrictMode> (#9664)
2 parents 5be85a0 + e62f8f6 commit 4571e1a

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
- Guarantee `Concast` cleanup without `Observable cancelled prematurely` rejection, potentially solving long-standing issues involving that error. <br/>
66
[@benjamn](https://github.com/benjamn) in [#9701](https://github.com/apollographql/apollo-client/pull/9701)
77

8+
- Ensure `useSubscription` subscriptions are properly restarted after unmounting/remounting by React 18 in `<StrictMode>`. <br/>
9+
[@benjamn](https://github.com/benjamn) in [#9707](https://github.com/apollographql/apollo-client/pull/9707)
10+
811
### Improvements
912

1013
- Internalize `useSyncExternalStore` shim, for more control than `use-sync-external-store` provides, fixing some React Native issues. <br/>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
{
5757
"name": "apollo-client",
5858
"path": "./dist/apollo-client.min.cjs",
59-
"maxSize": "29.45kB"
59+
"maxSize": "29.5kB"
6060
}
6161
],
6262
"engines": {

src/react/hooks/useSubscription.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ export function useSubscription<TData = any, TVariables = OperationVariables>(
3838
});
3939
});
4040

41+
const canResetObservableRef = useRef(false);
42+
useEffect(() => {
43+
return () => {
44+
canResetObservableRef.current = true;
45+
};
46+
}, []);
47+
4148
const ref = useRef({ client, subscription, options });
4249
useEffect(() => {
4350
let shouldResubscribe = options?.shouldResubscribe;
@@ -46,23 +53,24 @@ export function useSubscription<TData = any, TVariables = OperationVariables>(
4653
}
4754

4855
if (options?.skip) {
49-
if (!options?.skip !== !ref.current.options?.skip) {
56+
if (!options?.skip !== !ref.current.options?.skip || canResetObservableRef.current) {
5057
setResult({
5158
loading: false,
5259
data: void 0,
5360
error: void 0,
5461
variables: options?.variables,
5562
});
5663
setObservable(null);
64+
canResetObservableRef.current = false;
5765
}
5866
} else if (
59-
shouldResubscribe !== false && (
60-
client !== ref.current.client ||
61-
subscription !== ref.current.subscription ||
62-
options?.fetchPolicy !== ref.current.options?.fetchPolicy ||
63-
!options?.skip !== !ref.current.options?.skip ||
64-
!equal(options?.variables, ref.current.options?.variables)
65-
)
67+
(shouldResubscribe !== false &&
68+
(client !== ref.current.client ||
69+
subscription !== ref.current.subscription ||
70+
options?.fetchPolicy !== ref.current.options?.fetchPolicy ||
71+
!options?.skip !== !ref.current.options?.skip ||
72+
!equal(options?.variables, ref.current.options?.variables))) ||
73+
canResetObservableRef.current
6674
) {
6775
setResult({
6876
loading: true,
@@ -76,10 +84,11 @@ export function useSubscription<TData = any, TVariables = OperationVariables>(
7684
fetchPolicy: options?.fetchPolicy,
7785
context: options?.context,
7886
}));
87+
canResetObservableRef.current = false;
7988
}
8089

8190
Object.assign(ref.current, { client, subscription, options });
82-
}, [client, subscription, options]);
91+
}, [client, subscription, options, canResetObservableRef.current]);
8392

8493
useEffect(() => {
8594
if (!observable) {

0 commit comments

Comments
 (0)