聊天应用Apollo Client缓存最佳实践及跨房间消息混存问题求解
问题根因
chatDetail字段的缓存配置keyArgs仅声明了limit作为缓存区分参数,Apollo Client会将所有携带相同limit值的chatDetail查询判定为同一个缓存条目,忽略查询时传入的房间ID等区分参数,因此切换房间时新返回的消息会和上一个房间的缓存消息合并,导致页面展示出上一个房间的内容。
修复方案
修正keyArgs配置,将查询chatDetail时用来区分不同房间的参数(通常为roomId,请根据实际查询的变量名调整)加入keyArgs列表,让不同房间的查询对应独立的缓存空间:
const cache = new InMemoryCache({ typePolicies: { Query: { fields: { lastRooms: offsetLimitPagination(), lastTopics: offsetLimitPagination(), topicDetail: offsetLimitPagination(), chatDetail: { // 新增房间标识参数到keyArgs,如查询时传的是roomId则加roomId keyArgs:['roomId', 'limit'], merge(existing=[], incoming=[], { readField }) { try { let merged = existing const existingIdSet = new Set(merged.map(message => readField("_id", message))); if (incoming) { incoming = incoming.filter(message => !existingIdSet.has(readField("_id", message))) } return [...merged, ...incoming] } catch (error) { console.log("Apollo Cache chatDetail Query fields Error:", error); } } }, } } }, });
修改后同个房间的分页消息依然会按原有逻辑去重合并,不同房间的缓存完全隔离,不会出现消息串扰的问题。
参考截图
- 房间列表

- 首个房间消息(共2条)

- K3房间消息(共16条)

内容的提问来源于stack exchange,提问作者rufai demir
相关产品推荐
相关产品推荐

