ApolloGraphQL useSubscription钩子结合onSubscriptionData的正确用法
正确使用Apollo useSubscription的onSubscriptionData钩子
你的基础代码思路是对的,只是onSubscriptionData的回调函数需要正确接收OnSubscriptionDataOptions类型的参数——这个参数里包装了你需要的订阅数据和Apollo客户端实例,我给你梳理下完整的正确用法:
完整代码示例
// 先定义你的订阅GraphQL查询 const INCOMING_MESSAGES_SUBSCRIPTION_QUERY = gql` subscription IncomingMessages($localUserId: ID!) { incomingMessages(localUserId: $localUserId) { id senderId content timestamp } } `; // 定义订阅数据到达时的处理函数 const handleNewSubscriptionData = ({ subscriptionData, client }) => { // 实际的业务数据在subscriptionData.data里 const newMessage = subscriptionData.data?.incomingMessages; if (newMessage) { // 这里可以执行你需要的逻辑:比如更新缓存、触发通知、更新组件状态等 console.log("收到新消息:", newMessage); // 示例:用Apollo Client手动更新缓存(如果需要把新消息合并到现有列表) client.cache.modify({ fields: { messages(existingMessages = []) { return [...existingMessages, newMessage]; } } }); } }; // 在组件中使用useSubscription const MessagesList = () => { const localUserId = Meteor.userId(); const { loading, error, data } = useSubscription( INCOMING_MESSAGES_SUBSCRIPTION_QUERY, { variables: { localUserId }, onSubscriptionData: handleNewSubscriptionData } ); if (loading) return <div>订阅加载中...</div>; if (error) return <div>订阅出错:{error.message}</div>; return ( <div className="messages-container"> {/* 渲染你的消息列表 */} </div> ); };
关键细节说明
onSubscriptionData的回调函数接收一个对象参数,这个对象就是OnSubscriptionDataOptions<TData>,核心包含两个属性:subscriptionData: 包装了推送的新数据,实际业务数据在subscriptionData.data字段中client: 当前的Apollo Client实例,可用来操作缓存、发起额外请求等
- 你也可以选择内联编写回调函数,简化代码:
useSubscription( INCOMING_MESSAGES_SUBSCRIPTION_QUERY, { variables: { localUserId: Meteor.userId() }, onSubscriptionData: ({ subscriptionData }) => { console.log("新推送数据:", subscriptionData.data); // 直接在这里写处理逻辑 } } );
常见误区提醒
别直接访问subscriptionData本身,它是一个包含元数据的包装对象,你需要的业务数据一定在subscriptionData.data里面。
内容的提问来源于stack exchange,提问作者VikR
相关产品推荐
相关产品推荐

