大多数示例在查询组件中使用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
并在每个渲染中比较两个吗?
对所有这些都有更优雅的方法吗?
答案 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)