【问题标题】:How can I refetch() my Query only when new subscription data arrives?仅当新订阅数据到达时,我如何才能重新获取()我的查询?
【发布时间】:2018-10-14 03:52:19
【问题描述】:

大多数示例在查询组件中使用 subscribeToMore,但在我的情况下,查询和订阅返回的数据非常不同,所以我认为我需要一个离散的订阅组件。

我将时间序列数据添加到触发onChangedWeatherIntervals 订阅的数据库中,该订阅返回有关新时间序列信息的摘要信息。如果新的时间序列信息与 React 客户端的过滤器匹配,它应该请求更新直方图 getHistogram 查询。

我的测试代码:

<Query
  query={gql`
    {
      getHistogram (deviceID:"ARMS-NVM-P16", startTimestamp:1525201056) {
        columns {
          binWidth
          binHeight
          binCenter
        }
      }
     }
  `}
>
  {({
      loading: queryLoading,
      error: queryError,
      data: queryData,
      refetch
    }) => (
    <Subscription
      subscription={gql`
        subscription onChangedWeatherIntervals {
          onChangedWeatherIntervals {
            changedItems {
              deviceID
              timestamp
              siteKey
            }
          }
        }
      `}>
      {({
          data: subscriptionData,
          loading: subscriptionLoading,
          error: subscriptionError
        }) => {
        if (subscriptionData && !subscriptionLoading) {
          console.log("subscriptionData: ", subscriptionData);
          //TODO: Add code to inspect subscriptionData & determine if we refetch
          //refetch() //Uncommenting causes refetch loop after first server push
        }
        if (queryData && !queryLoading) {
          console.log("queryData: ", queryData.getHistogram.columns);
          return (<p>{queryData.getHistogram.columns[0].binWidth}</p>);
        }
        return null
      }}
    </Subscription>
  )
  }
</Query>

因为subscriptionLoadingtrue 仅在挂载后的第一个服务器推送之前,我不确定区分重新渲染和新订阅数据的最佳方法。我应该将subscriptionData 存储到state.subscriptionData 并在每次渲染时比较两者吗?

有没有更优雅的方法来解决所有这些问题?

【问题讨论】:

    标签: reactjs graphql react-apollo


    【解决方案1】:

    您是否曾尝试在查询中使用subscribeToMore?您可能可以在其 updateQuery 属性中调用 refetch。

    更新:我碰巧在我的应用程序中遇到了同样的问题,并找到了解决它的方法。随时查看here。基本上你应该避免将你的订阅逻辑放在一个 render 方法中,这会导致无限的重新获取/重新渲染问题。解决方案是将逻辑从渲染方法中移出,并将其放入生命周期方法中,例如componentDidMount。这样在触发重新获取后就不会再次调用 subscribe。

    这是您案例的代码 sn-p。 (我使用了来自 'react-apollo' 的 hoc graphql 来帮助将查询的 refetchsubscribeToMore 注入到 props 中。

    import { graphql } from 'react-apollo';
    
    class YourComponent extends React.Component {
      componentDidMount() {
        const { data: { refetch, subscribeToMore }} = this.props;
    
        this.unsubscribe = subscribeToMore({
          document: <ON_CHANGED_WEATHER_INTERVALS>,
          updateQuery: (prev) => {
            refetch();
            return prev;
          },     
        });
      }
    
      componentWillUnmount() {
        this.unsubscribe();
      }
    
      render() {
        const { data: {queryData, loading, error } } = this.props;
    
        if (loading || error) return null;
    
        return <p>{queryData.getHistogram.columns[0].binWidth}</p>
      }
    }
    
    export default graphql(GET_HISTOGRAM, {
      options: {
        variables: {
          deviceID: 'ARMS-NVM-P16',
          startTimestamp:1525201056,
        },
      },
    })(YourComponent)
    

    【讨论】:

    • 谢谢。使用 refetch() 对我来说效果很好!
    • @vemund 很高兴它有帮助!
    猜你喜欢
    • 2018-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-21
    • 2017-11-11
    • 2017-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多