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