Reactjs 如何仅在新订阅数据到达时才重新提取查询?

Reactjs 如何仅在新订阅数据到达时才重新提取查询?,reactjs,graphql,react-apollo,Reactjs,Graphql,React Apollo,大多数示例在查询组件中使用subscribeToMore,但在我的示例中,查询和订阅返回的数据非常不同,因此我认为需要一个离散订阅组件 我将时间序列数据添加到数据库,触发onChangedWeatherIntervals订阅,该订阅返回有关新时间序列信息的摘要信息。如果新的时间序列信息与React客户端的过滤器匹配,则应请求更新的直方图getHistogram查询 我的测试代码: <Query query={gql` { getHistogram (deviceID

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

{({
加载:查询加载,
错误:queryError,
数据:queryData,
重新蚀刻
}) => (
{({
数据:subscriptionData,
加载:订阅加载,
错误:subscriptionError
}) => {
if(subscriptionData&!subscriptionLoading){
log(“subscriptionData:,subscriptionData”);
//TODO:添加代码以检查subscriptionData并确定是否重新蚀刻
//refetch()//取消注释会在第一次服务器推送后导致refetch循环
}
if(queryData&!queryload){
log(“queryData:,queryData.getHistogram.columns”);
返回({queryData.getHistogram.columns[0].binWidth}

); } 返回空 }} ) }
因为
subscriptionLoading
仅在装载后的第一次服务器推送之前是
true
,所以我不确定区分重新渲染和新subscriptionData的最佳方法。我是否应该将
subscriptionData
存储到
state.subscriptionData
并在每次渲染时比较这两个数据


有没有更优雅的方法来处理所有这些问题?

您是否尝试过在查询中使用这些方法?您可能可以在其updateQuery道具中调用refetch

更新:我碰巧在我的应用程序中遇到了同样的问题,并找到了解决方法。请随意查看。基本上,您应该避免将订阅逻辑放在渲染方法中,这将导致无限重绘/重绘问题。解决方案是将逻辑移出render方法,并将其放入像componentDidMount这样的生命周期方法中。这样,在触发重新蚀刻后,将不会再次调用subscribe

下面是您案例的代码片段。(我使用“react apollo”中的hoc graphql帮助将查询的refetch和subscribeToMore注入到道具中)

从'react apollo'导入{graphql};
类YourComponent扩展React.Component{
componentDidMount(){
const{data:{refetch,subscribeToMore}}=this.props;
this.unsubscribe=subscribeToMore({
文件:,
updateQuery:(上一个)=>{
重新蚀刻();
返回上一个;
},     
});
}
组件将卸载(){
这个。取消订阅();
}
render(){
const{data:{queryData,loading,error}}=this.props;
如果(加载| |错误)返回null;
return{queryData.getHistogram.columns[0].binWidth}

} } 导出默认图形ql(获取直方图{ 选项:{ 变量:{ 设备ID:'ARMS-NVM-P16', startTimestamp:1525201056, }, }, })(组成部分)
谢谢您的帮助。使用refetch()对我来说非常有用@维蒙很高兴这有帮助!
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)