分页功能适配:需从updateQuery迁移至Apollo Client字段策略
解决Apollo Client fetchMore弃用警告与缓存数据丢失问题
问题背景
原本通过fetchMore的updateQuery实现分页(初始展示10条,点击加载更多追加10条),但收到弃用警告:The updateQuery callback for fetchMore is deprecated, and will be removed in the next major version of Apollo Client。改用缓存字段策略后,又出现警告:Cache data may be lost when replacing the set field of a Block object。
解决方案
1. 修正缓存类型策略
原策略仅针对Query.sezione配置,未匹配实际数据层级的类型。需要针对Block和PagedItems类型配置合并规则,避免替换字段时丢失缓存:
const cache = new InMemoryCache({ typePolicies: { Block: { fields: { set: { // 基于set的uuid识别同一对象,防止直接替换整个set keyArgs: ["uuid"], merge(existing, incoming) { if (!incoming) return existing; if (!existing) return incoming; // 合并set下的pagedItems,重点追加items列表 return { ...existing, ...incoming, pagedItems: { ...existing.pagedItems, ...incoming.pagedItems, items: [...existing.pagedItems.items, ...incoming.pagedItems.items] } }; } } } }, // 单独给PagedItems的items配置合并策略,增强通用性 PagedItems: { fields: { items: { merge(existing = [], incoming) { return [...existing, ...incoming]; } } } } } });
2. 简化fetchMore实现
移除updateQuery回调,由缓存策略自动处理数据合并:
const onFetchMore = useCallback(() => { const { page: { apertura, block: { set: { pagedItems: { items }, }, }, }, } = data; fetchMore({ variables: { limit: 10, exclude: [apertura.set.first.uuid].concat( items.map((articolo) => articolo.uuid) ), }, // 移除updateQuery,缓存策略自动合并数据 }); }, [data, fetchMore]);
注意事项
- 确保配置中的类型名(
Block、PagedItems)与GraphQL返回的__typename完全一致,比如原数据中的blockTypeName对应Block,需根据实际返回值调整。 - 确认
Set类型存在唯一标识字段(如uuid),让Apollo能识别同一对象并执行合并,而非直接替换。
内容的提问来源于stack exchange,提问作者Davide la Fogia
相关产品推荐
相关产品推荐

