ApolloGraphQL 和 React:组件重新挂载时避免调用查询和订阅?
Posted
技术标签:
【中文标题】ApolloGraphQL 和 React:组件重新挂载时避免调用查询和订阅?【英文标题】:ApolloGraphQL & React: Avoid Calling Query & Subscription When Component Re-Mounts? 【发布时间】:2019-08-26 17:40:19 【问题描述】:我有一个这样设置的 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】:将变量 在 unsubscribeFromIncomingMessages
设为全局变量并<Query>
上添加 fetchPolicy='cache-first'
。
编辑: 哎呀,我想我应该预料到的。无论您将参考存储在何处,订阅都会在您离开路线后立即停止。
subscribeToMore
将在您每次进入路线时运行。除非您需要能够停止订阅,否则您不需要记录对它的引用。入门时设置订阅并不昂贵。
如果您需要在不同的路由中激活相同的订阅,您也需要在这些路由上运行它。
我的理解是,订阅不会每次都重新订阅,它只是从上次订阅相同变量等的地方重新开始。
【讨论】:
成功了!有趣的是,我有几个按钮使用<a href=...>
,它们导致整个站点从头开始重新加载,包括重新声明全局变量。我将它们替换为onClick=() => props.history.push(theHref)
,就解决了。
更新——我不知道为什么一开始它似乎在工作——但将它移动到全局似乎会杀死订阅。嗯.....我想知道这里还有什么最佳做法?
感谢您提供此信息。您能否告诉我,<Subscription> component
中的情况是否相同——即它是否在每次刷新时重新订阅——并在每次卸载组件时取消订阅?
是的,它也会在卸载每个组件时停止。以上是关于ApolloGraphQL 和 React:组件重新挂载时避免调用查询和订阅?的主要内容,如果未能解决你的问题,请参考以下文章
Apollo graphql 连接的 React 组件没有重新渲染
Apollo GraphQL (React) 跨组件数据共享