У меня есть маршрутизатор 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> и подписка выполняются снова и снова.
Каков правильный способ решить эту проблему?
ОБНОВИТЬ
Точка останова на моем сервере в запросе на подписку срабатывает каждый раз, когда я перехожу на новую страницу на моем клиенте.
Произойдет ли это предполагаемый? Если это так, хорошо! Но если нет... Я хотел бы это знать. :)





Сделать переменную добавить unsubscribeFromIncomingMessages глобальной иfetchPolicy='cache-first' к <Query>.
Обновлено: Ой, я полагаю, я должен был ожидать этого. Подписка прекратится, как только вы уйдете с маршрута, независимо от того, где вы храните ссылку.
subscribeToMore будет запускаться каждый раз, когда вы входите в маршрут. Если вам не нужно иметь возможность остановить подписку, вам не нужно записывать ссылку на нее. Не дорого настроить подписку при входе.
Если вам нужна одна и та же подписка, активная на разных маршрутах, вам нужно будет запустить ее и на этих маршрутах.
Насколько я понимаю, подписка не переподписывается каждый раз, она просто продолжается там, где остановилась последняя подписка с теми же переменными и т. д.
Обновление - я понятия не имею, почему сначала он работал, но перемещение его в глобальное, похоже, убивает подписку. Хммм..... Интересно, что еще может быть здесь лучшей практикой?
Спасибо за эту информацию. Можете ли вы случайно сказать мне, то же самое в <Subscription> component -- т.е. он переподписывается при каждом обновлении -- и отменяет подписку при каждом размонтировании компонента?
Да, он также остановится при размонтировании каждого компонента.
Это сработало! Интересно, что у меня была пара кнопок с использованием
<a href=...>, и они вызывали перезагрузку всего сайта с нуля, включая повторное объявление глобальной переменной var. Я заменил их наonClick = {() => props.history.push(theHref)}, и это решило проблему.