Apollo cache-and-network策略下分页merge函数重复数据如何解决?
可以区分两种请求场景,以下是几种生产环境常用的解决方案:
方案一:自定义上下文标记(通用性最高)
这是最稳妥的实现方式,不受分页类型(offset/cursor)限制,不会出现逻辑误判:
- 调用
fetchMore时传入自定义上下文标记
fetchMore({ variables: { // 你的分页参数,比如offset/page/cursor等 offset: existingList.length }, context: { isFetchMore: true } })
- 修改字段策略的merge函数,根据标记执行对应逻辑
merge(existing = [], incoming, { context }) { // 仅fetchMore请求执行追加逻辑,其余场景(包含cache-and-network的网络回包)直接覆盖缓存 if (context.isFetchMore) { return [...existing, ...incoming]; } return incoming; }
方案二:通过分页参数判断(无需额外传参)
如果你的分页采用offset+limit的实现,初始请求的offset固定为0,可以直接通过参数判断,无需修改fetchMore的调用逻辑:
merge(existing = [], incoming, { args }) { // offset大于0时为分页加载,执行追加;offset为0的初始请求直接覆盖 if (args?.offset > 0) { return [...existing, ...incoming]; } return incoming; }
兜底方案:基于唯一标识去重
如果不想区分请求场景,也可以直接在merge时对数据做去重处理,从根源避免重复:
merge(existing = [], incoming) { const existedIds = new Set(existing.map(item => item.id)); const uniqueNewItems = incoming.filter(item => !existedIds.has(item.id)); return [...existing, ...uniqueNewItems]; }
内容的提问来源于stack exchange,提问作者Márton Borlay
相关产品推荐
相关产品推荐

