ApolloGraphQL и React: избегайте вызова запроса и подписки при повторном монтировании компонента?

У меня есть маршрутизатор 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> и подписка выполняются снова и снова.

Каков правильный способ решить эту проблему?

ОБНОВИТЬ

Точка останова на моем сервере в запросе на подписку срабатывает каждый раз, когда я перехожу на новую страницу на моем клиенте.

Произойдет ли это предполагаемый? Если это так, хорошо! Но если нет... Я хотел бы это знать. :)

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
554
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Сделать переменную unsubscribeFromIncomingMessages глобальной и добавить fetchPolicy='cache-first' к <Query>.

Обновлено: Ой, я полагаю, я должен был ожидать этого. Подписка прекратится, как только вы уйдете с маршрута, независимо от того, где вы храните ссылку.

subscribeToMore будет запускаться каждый раз, когда вы входите в маршрут. Если вам не нужно иметь возможность остановить подписку, вам не нужно записывать ссылку на нее. Не дорого настроить подписку при входе.

Если вам нужна одна и та же подписка, активная на разных маршрутах, вам нужно будет запустить ее и на этих маршрутах.

Насколько я понимаю, подписка не переподписывается каждый раз, она просто продолжается там, где остановилась последняя подписка с теми же переменными и т. д.

Это сработало! Интересно, что у меня была пара кнопок с использованием <a href=...>, и они вызывали перезагрузку всего сайта с нуля, включая повторное объявление глобальной переменной var. Я заменил их на onClick = {() => props.history.push(theHref)}, и это решило проблему.

VikR 05.04.2019 03:41

Обновление - я понятия не имею, почему сначала он работал, но перемещение его в глобальное, похоже, убивает подписку. Хммм..... Интересно, что еще может быть здесь лучшей практикой?

VikR 12.04.2019 01:17

Спасибо за эту информацию. Можете ли вы случайно сказать мне, то же самое в <Subscription> component -- т.е. он переподписывается при каждом обновлении -- и отменяет подписку при каждом размонтировании компонента?

VikR 14.04.2019 09:21

Да, он также остановится при размонтировании каждого компонента.

Paul Parker 14.04.2019 14:36

Другие вопросы по теме