如何在新订阅数据到达时重新获取()我的查询?

时间:2018-05-03 18:29:23

标签: reactjs graphql react-apollo

大多数示例在查询组件中使用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>

因为subscriptionLoading仅在安装后的第一个服务器推送之前是true,所以我不确定区分重新呈现和新订阅数据的最佳方法。我应该将subscriptionData存储到state.subscriptionData并在每个渲染中比较两个吗?

对所有这些都有更优雅的方法吗?

1 个答案:

答案 0 :(得分:1)

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

更新:我碰巧在我的应用中遇到了同样的问题,并想出了一种解决方法。随时检查here。基本上,您应该避免将订阅逻辑放在 render 方法中,这将导致无限的重新获取/重新呈现问题。解决方案是将逻辑移出render方法,并将其放入生命周期方法中,例如componentDidMount。这样一来,在触发重新获取后,订阅将不再被调用。

这是您的案例的代码段。 (我使用了来自'react-apollo'的hoc graphql 来帮助将查询的 refetch subscribeToMore 注入到道具中。)

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)