ApolloGraphQL&React:避免在组件重新安装时调用查询和订阅吗?

时间:2019-04-04 21:04:00

标签: reactjs react-router apollo react-apollo apollo-client

我有一个这样的React路由器:

       <ApolloProvider client={ApolloClient}>
            <Router history={browserHistory}>
                <React.Suspense fallback={<p></p>}>
                    <ErrorBoundary>
                        <AppStateProvider>
                            <Route render={(routeProps) =>
                                <TopNav
                                    history={routeProps.history}
                                    match={routeProps.match}
                                />
                            }/>
                            <Switch>
                                <Route exact path="/" render={(routeProps) =>
                                    <myComponent history={routeProps.history} match={routeProps.match}
                                    />
                                }/>

                                [.....MORE COMPONENTS.....]

                            </Switch>
                            <Route render={(routeProps) =>
                                <BottomNav history={routeProps.history} match={routeProps.match}
                                />
                            }/>
                        </AppStateProvider>
                    </ErrorBoundary>
                </React.Suspense>
            </Router>
        </ApolloProvider>

<TopNav>组件包含一个Apollo查询和订阅:

function TopNav(props) {

[.......]

let unsubscribeFromIncomingMessages = null; <=== re-runs when user changes routes

[.......]

       <Query query={INCOMING_MESSAGES_QUERY}
               variables={{"localUserId": Meteor.userId()}}>
            {({subscribeToMore, loading, error, data, refetch}) => {
                if (loading) {
                    return (
                        <div key="divLoading"></div>);
                } else {
                }
                if (error) {
                    return (
                        <div key="divError"></div>);
                }

                if (!unsubscribeFromIncomingMessages) {
                    unsubscribeFromIncomingMessages = subscribeToMore({
                        document: INCOMING_MESSAGES_SUBSCRIPTION_QUERY,
                        variables: {
                            "localUserId": Meteor.userId()
                        },
                        updateQuery: (prev, {subscriptionData}) => {
                            [.....HANDLE UPDATE DATA.....]
                        }
                    });
                }

                return (
                    <>
                    </>
                );

            }}
        </Query>

当客户端在我的应用程序中提出另一条路由时,<TopNav>被重新挂载,这很好,但是<Query>和订阅又重新运行了。

解决此问题的正确方法是什么?

更新

订阅查询中服务器上的一个断点,每次我导航到客户端上的新页面时都会被命中。

应该发生吗?如果是这样,很好!但是,如果没有,我想知道。 :)

1 个答案:

答案 0 :(得分:1)

使变量unsubscribeFromIncomingMessages为全局变量,并fetchPolicy='cache-first'上添加<Query>

编辑: 糟糕,我想我应该已经预料到了。无论您将引用存储在何处,只要您离开路线,订阅都会立即停止。

subscribeToMore将在您每次输入路线时运行。除非您需要能够停止订阅,否则不需要记录对其的引用。在条目上设置订阅并不昂贵。

如果您需要在不同的路由中激活同一预订,则也需要在这些路由上运行它。

我的理解是,订阅不会每次都重新订阅,它只是选择了最后一个具有相同变量等的订阅从何处终止。