【问题标题】:ApolloGraphQL & React: Avoid Calling Query & Subscription When Component Re-Mounts?ApolloGraphQL 和 React:组件重新挂载时避免调用查询和订阅?
【发布时间】: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>

&lt;TopNav&gt; 组件包含一个 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>

当客户端在我的应用程序中调出另一条路由时,&lt;TopNav&gt; 会重新挂载,这很好,但&lt;Query&gt; 和订阅会重新运行。

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

更新

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

应该会发生吗?如果是,那就好!但如果不是——我想知道这一点。 :)

【问题讨论】:

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


    【解决方案1】:

    将变量 unsubscribeFromIncomingMessages 设为全局变量并&lt;Query&gt; 上添加 fetchPolicy='cache-first'

    编辑: 哎呀,我想我应该预料到的。无论您将参考存储在何处,订阅都会在您离开路线后立即停止。

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

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

    我的理解是,订阅不会每次都重新订阅,它只是从上次订阅相同变量等的地方重新开始。

    【讨论】:

    • 成功了!有趣的是,我有几个按钮使用&lt;a href=...&gt;,它们导致整个站点从头开始重新加载,包括重新声明全局变量。我将它们替换为onClick={() =&gt; props.history.push(theHref)},就解决了。
    • 更新——我不知道为什么一开始它似乎在工作——但将它移动到全局似乎会杀死订阅。嗯.....我想知道这里还有什么最佳做法?
    • 感谢您提供此信息。您能否告诉我,&lt;Subscription&gt; component 中的情况是否相同——即它是否在每次刷新时重新订阅——并在每次卸载组件时取消订阅?
    • 是的,它也会在卸载每个组件时停止。
    猜你喜欢
    • 2020-08-24
    • 1970-01-01
    • 2017-05-04
    • 2023-03-23
    • 1970-01-01
    • 2010-10-23
    • 2018-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多