【问题标题】:Apollo run a query and listen to changesApollo 运行查询并监听变化
【发布时间】:2018-07-20 18:45:00
【问题描述】:

我的 apollo 项目开始变大,我遇到的问题是如何使本地缓存与数据库保持同步。例如,我将更改突变的响应,然后发现其他一些查询取决于响应类型。这将我的查询耦合在一起,并且越来越难以进行更新。

我想要通过 websocket 运行我的所有查询。 IE。数据库是事实的来源,当 websocket 发出更改时,所有数据都会刷新。

阅读此https://github.com/apollographql/subscriptions-transport-ws#full-websocket-transport 后,我相信这是可能的,但是当我运行查询时,我只会得到一个响应,而当我运行订阅时,我只会在项目更改时得到响应。

有谁知道我如何以这种方式利用阿波罗?

【问题讨论】:

    标签: graphql apollo react-apollo apollo-client


    【解决方案1】:

    我相信您要求的功能称为“实时查询”,尚未实现(2018 年 11 月 2 日)。目前最好的办法是使用订阅来近似。

    我想要通过 websocket 运行我的所有查询。 IE。数据库是事实的来源,所有数据都会在 websocket 发出更改时刷新。

    让我们尝试采用这种方法:假设您只有 1 个订阅,并且每次数据库发生更改时,您都会针对该订阅发出通知。

    在大多数用例中,人们接收修改后的对象并将其手动集成到本地数据中。您的方法似乎建议避免手动集成并重新获取整个查询。

    对于这种方法,您可以构建一个高阶组件 (HOC) 来侦听该单个订阅,当它发出某些内容时,该组件将强制重新获取 Apollo 查询。为了帮助我们,我们将使用 Apollo 提供的辅助方法来让您做一些手动工作。 https://www.apollographql.com/docs/react/basics/queries.html#default-result-props

    实际上,https://www.apollographql.com/docs/react/features/subscriptions.html 的文档似乎与 API 文档不同步。因此,我将使用一种方法来启动订阅而不将其连接到组件。

    import { graphql } from 'react-apollo';
    import gql from 'graphql-tag';
    import React from 'react';
    import PT from 'prop-types';
    
    
    //
    // Create an observable to a standalone graphql subscription.
    // Any component can then observe that observable.
    // 
    
    const ANYTHING_SUBSCRIPTION = gql`
        subscription onAnythingChanged() {
            onAnythingChanged { id }
        }
    `;
    
    let anythingObservable = apolloClient.queryManager.startGraphQLSubscription({
        query: ANYTHING_SUBSCRIPTION,
        variables: {},
    });
    
    //
    // End of observable creation.
    //
    
    
    const ALL_COMMENTS_QUERY = gql`
        query AllComments() { 
            comments { id content } 
        }
    `;
    
    
    const withComments = graphql( ALL_COMMENTS_QUERY, { name: 'comments' } );
    
    
    let Component = React.createClass({
    
        propTypes: {
            comments: PT.shape({
                refetch: PT.func.isRequired
            }),
        }
    
        componentWillMount: function () {
    
            let anythingSubscription = anythingObservable.subscribe({
                next: ( data ) => {
                    console.log("SUBSCRIPTION EMITTED:", data );
                    this.props.comments.refetch(); // Refetch comment query
                },
                error: ( err ) => {
                    console.log("SUBSCRIPTION ERROR:", err );
                }
           });
    
           // In real code you should save anythingSubscription somewhere
           // to destroy it in the future.
    
        }
    }
    
    
    let ComponentWithCommentsAndRefetchSubscription = withComments(Component);
    
    export default ComponentWithCommentsAndRefetchSubscription;
    

    我希望这能给你一个好的起点。

    请记住,在发生任何变化时重新获取所有查询并不是一种非常有效的方法。您可以通过使组件仅观察特定类别(评论、帖子等)并跳过重新获取来改进它。

    您还可以选择为每个组件添加订阅,或者在全局内存中的某个位置(例如 Redux)有一个全局订阅,所有组件都会监​​听。

    【讨论】:

    • 非常有帮助。谢谢。
    猜你喜欢
    • 2020-12-30
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    相关资源
    最近更新 更多