apollographql / react-apollo

:recycle: React integration for Apollo Client
https://www.apollographql.com/docs/react/
MIT License
6.85k stars 787 forks source link

subscribeToMore is not subscribing, while previous subscription is being unsubscribed #3249

Closed inaniyants closed 5 years ago

inaniyants commented 5 years ago

Imagine situation, when multiple components are using same query, and both are using subscribeToMore in componentDidMount. When first component is unmounted, second component is mounted. In this situation second component is not subscribed to subscription, since its call to subscribeToMore is ignored (since subscription is already exists), but this subscription will actually be unsubscribed in a moment, since first component is being unmounted.

Intended outcome:

In my functionality I have 2 tabs, each of it is defining same query as child. Every tab uses subscribeToMore of this query. When I'm switching to the second tab I'm expecting first tab query will unsubscribe and second tab query will subscribe once again.

Actual outcome:

When I'm switching to the second tab, second tab is not subscribed as expected.

How to reproduce the issue:

class Chat extends React.Component {
    componentDidMount = () => {
        const { subscribeToNewMessages } = this.props
        subscribeToNewMessages()
    }
}

class Tab1 extends React.Component {
    render() {
        <Query query={CHAT_MESSAGES_QUERY}>
           {({ data, loading, subscribeToMore }) => {
                 return <Chat subscribeToNewMessages={() => {subscribeToMore(
                   document: NEW_MESSAGE_SUBCRIPTION,
                   variables: {},
                 )}} />
           }}
        </Query>
       ... other tab1 content
    }
}

// Tab2 has same code, the only difference is other content.

class TabSwitcher extends React.Component {
    render() {
         const { currentTabIndex } = this.state

         return currentTabIndex === 1 ? (Tab1) : (Tab2)
    }
}

When switching tab and looking into websocket debug I only see unsubscribe, but no subscribe. As a workaround I have added setTimeout into Chat component, like this:

class Chat extends React.Component {
    componentDidMount = () => {
        const { subscribeToNewMessages } = this.props
        setTimeout(subscribeToNewMessages, 1000)
    }
}

and now all working as expected.

By the way, since both tab using same query, when I'm switching to Tab2, query data is fetched from cache, probably that is why previous tab query unsubscription is not getting in time.

Version apollo-client@2.6.3 react-apollo@2.5.8

hwillson commented 5 years ago

React Apollo has been refactored to use React Hooks behind the scenes for everything, which means a lot has changed since this issue was opened (and a lot of outstanding issues have been resolved). We'll close this issue off, but please let us know if you're still encountering this problem using React Apollo >= 3.1.0. Thanks!

michellechsy commented 4 years ago

I'm using 3.1.5 for react-apollo, but it keeps say there's no 'subscribeToMore', any suggestion?