question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Inside StrictMode useSubscription subscribes twice

See original GitHub issue

Intended outcome:

useSubscription should subscribe only once when run inside <StrictMode>

Actual outcome:

useSubscription subscribes twice to the same subscription. I think that this happens because <StrictMode> intentionally runs component bodies twice. I suppose that same thing could happen in concurrent mode too.

This results in double network traffic. Also, the second subscription won’t get unsubscribed when the useSubscription is unmounted.

This can be inspected on chrome network tab: usesubscription_chrome in the picture, id 15 and 16 are the single useSubscription and receive the same data. After unmount the id 16 was closed and id 15 was left receiving data(not pictured).

I am not familiar with apollo-client codebase, but I think that this is result of the following line being run in function body instead of inside useEffect: https://github.com/apollographql/apollo-client/blob/23b17fa7283b21966d1c633c52b848f12b4a211e/src/react/hooks/useSubscription.ts#L44

How to reproduce the issue:

Any subscription should behave the same when run in StrictMode.

const SubComponent = ({vesselId}) => {
  const { data } = useSubscription(vesselStatus, {
    variables: { vesselId }
  });
  return null;
}
<StrictMode>
  <SubComponent vesselId="245" />
</StrictMode>

Workaround is to not use StrictMode, but I’m afraid that will result in code that breaks when concurrent mode lands in React.

Versions

System: OS: macOS 10.15.3 Binaries: Node: 12.16.1 - ~/.nvm/versions/node/v12.16.1/bin/node Yarn: 1.22.0 - ~/.nvm/versions/node/v12.16.1/bin/yarn npm: 6.13.4 - ~/.nvm/versions/node/v12.16.1/bin/npm Browsers: Chrome: 80.0.3987.132 Firefox: 73.0.1 Safari: 13.0.5 npmPackages: @apollo/client: ^3.0.0-beta.39 => 3.0.0-beta.39 @apollo/link-ws: ^2.0.0-beta.3 => 2.0.0-beta.3 apollo-server-express: ^2.11.0 => 2.11.0 npmGlobalPackages: apollo-codegen: 0.20.2 apollo: 2.24.0

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:58
  • Comments:37

github_iconTop GitHub Comments

19reactions
anajavicommented, Jul 16, 2020

I agree, this is annoying. In my case I listen for events and display an alert for each of them in the UI which turns out to be duplicated. However the problem does not come from Apollo-Client, it is React strict mode behavior… I don’t think we can expect a fix coming from Apollo to remove this behavior since it is external to Apollo-Client.

There is a reason for strict mode rendering twice. It is to prevent bugs in the coming concurrent mode. So this should be fixed in apollo-client.

16reactions
stephencorwincommented, Jul 15, 2020

Try to run a production build and this effect will go away.

That might hide the symptoms, but having to run a production build when doing active development would get tedious and annoying real fast. We need a real solution for this issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

StrictMode causing double event subscription in React
When you subscribe in the constructor , it invoked twice, try to subscribe in the component's lifecycle where it supposed to be done....
Read more >
Subscriptions - Apollo GraphQL Docs
A GraphQL subscription document parsed into an AST by graphql-tag . Optional for the useSubscription Hook since the subscription can be passed in...
Read more >
use-subscription | Yarn - Package Manager
Design simple views for each state in your application, and React will efficiently update and render just the right components when your data...
Read more >
UseEffect called twice in React 18 - How to fix it? - YouTube
UseEffect called twice in React 18 - How to fix it? In the strict mode of React 18 an effect with useEffect seems...
Read more >
Realtime GraphQL Subscriptions with Node.JS Tutorial
Instead, the client initially opens up a long-lived connection to the server by sending a subscription query that specifies which event it is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found