我有一个这样的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>
和订阅又重新运行了。
解决此问题的正确方法是什么?
更新
订阅查询中服务器上的一个断点,每次我导航到客户端上的新页面时都会被命中。
是应该发生吗?如果是这样,很好!但是,如果没有,我想知道。 :)
答案 0 :(得分:1)
使变量在unsubscribeFromIncomingMessages
为全局变量,并fetchPolicy='cache-first'
上添加<Query>
。
编辑: 糟糕,我想我应该已经预料到了。无论您将引用存储在何处,只要您离开路线,订阅都会立即停止。
subscribeToMore
将在您每次输入路线时运行。除非您需要能够停止订阅,否则不需要记录对其的引用。在条目上设置订阅并不昂贵。
如果您需要在不同的路由中激活同一预订,则也需要在这些路由上运行它。
我的理解是,订阅不会每次都重新订阅,它只是选择了最后一个具有相同变量等的订阅从何处终止。