Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在React应用程序中处理订阅_Javascript_Reactjs_Graphql_React Apollo_Graphcool - Fatal编程技术网

Javascript 如何在React应用程序中处理订阅

Javascript 如何在React应用程序中处理订阅,javascript,reactjs,graphql,react-apollo,graphcool,Javascript,Reactjs,Graphql,React Apollo,Graphcool,我需要一些帮助来找出订阅和实时更新的通用方法。我有一个React原生应用程序,使用Apollo和GraphTool服务作为后端 有两种情况下,查看应用程序的用户会收到一个推送通知,表示某些内容已更改。当然,屏幕数据也应该得到更新。订阅是这份工作的一个明显的候选人,我基本上让它工作起来了 我有一个像这样的订阅,它自己就可以正常工作(用来在谷歌地图上定位玩家的头像) subscription PlayerMap($gameId:ID){ 游戏(筛选器:{u in:[已创建、已更新],节点:{id:$

我需要一些帮助来找出订阅和实时更新的通用方法。我有一个React原生应用程序,使用Apollo和GraphTool服务作为后端

有两种情况下,查看应用程序的用户会收到一个推送通知,表示某些内容已更改。当然,屏幕数据也应该得到更新。订阅是这份工作的一个明显的候选人,我基本上让它工作起来了

我有一个像这样的订阅,它自己就可以正常工作(用来在谷歌地图上定位玩家的头像)

subscription PlayerMap($gameId:ID){
游戏(筛选器:{u in:[已创建、已更新],节点:{id:$gameId}){
节点{
球员{
身份证件
性格{
身份证件
名称
}
使用者{
身份证件
纬度
经度
}
}
}
}
}
然后是一个不同的应用程序屏幕,执行Apollo(为简单起见)的
createPlayer
以及
refetchQueries
,Apollo运行此查询以更新内容

querygamecharacters($gameId:ID!){
游戏(id:$gameId){
球员{
身份证件
性格{
身份证件
名称
}
}
}
}
现在,当此操作完成时,订阅查询(在另一个屏幕上仍处于活动状态)也会得到更新,但由于某种原因,
数据
对象中缺少整个
游戏
节点

为了处理订阅,我有这样一个组件

类订户扩展组件{
componentDidMount(){
这个。订阅()
}
componentWillReceiveProps({data,shouldResubscribe}){
如果(此。取消订阅){
if(shouldResubscribe&&shouldResubscribe(数据,this.props.data)!==true){
返回
}
这个。取消订阅()
}
这个。订阅()
}
订阅(){
const{data,query,variables}=this.props
this.unsubscribe=data.subscribeToMore({
文件:查询,
变量,
})
}
取消订阅:?函数=null
render(){
返回this.props.children(this.props.data)
}
}
然后我可以像这样简单地使用渲染道具模式

const OrgMapScreen=({gameId,data:initialData}:Props)=>(
nextData.Game!==prevData.Game}
>
{({Game})=>{
const markers=Game.players.map(makePlayerMarker)
返回
}}
)
我很困惑为什么会这样。有什么推荐的方法来处理这样的事情吗?也许我不应该再订阅
refetchQueries
,我也应该为
GameCharacters
设置另一个订阅?

如果我不得不猜测(不是阿波罗专家),我会猜测这与
订阅模板中输入的
文档
错误有关(看起来您使用的是查询,而不是订阅作为参数?)或
subscribebetomore
中缺少的
updateQuery
,返回更新的数据

在我们的例子中,我们有一个
orderChanged
订阅,它监听
订单上的更改。当我们收到更新时,我们希望用更新的订单替换
orders
查询中的订单。我们在
subscribeToMore
中的
updateQuery
函数中执行此操作(为拼写错误道歉,这不是完全的复制粘贴):


如果你能为我提供最低限度的可行回购协议,我很乐意与你一起完成。我上周花了很多时间在订阅方面:)

是的,
updateQuery
是有必要的。我不知道为什么我会有这样的印象,阿波罗会自己抓取结果,并根据类型和
dataIdFromObject
更新存储。哦,好吧。像我这样的深层嵌套结构必须使用
immutable helper
,但它现在似乎可以工作了。谢谢
componentDidMount() {
  this.props.data.subscribeToMore({
    document: OrderSubscription,
    variables: {
      range: [0, 25]
    },
    updateQuery: (prev, { subscriptionData, }) => {
      // If no subscription data is passed, just return the previous
      // result from the initial `orders` query
      if (!subscriptionData.data) return prev

      // get the data for the updated order from the subscription 
      const updatedOrder = subscriptionData.data.orderChanged

      // find the index of the updated order from within the existing 
      // array of orders from the `orders` query
      const existingOrderIndex = prev.orders.findIndex(order => (order.id === updatedOrder.id))

      // guard for missing data
      if (existingOrderIndex) {
        // replace the old order with the updated order
        prev[existingOrderIndex] = updatedOrder
        // return orders with new, updated data
        return prev
      }

      return prev
    },
  })
}