Apollo Client fetchMore执行后触发重复网络请求问题求助
以下是针对你遇到问题的具体排查和修复建议:
确认fetchMore的变量传递正确性
确保调用fetchMore时,offset参数是基于已加载数据的长度累加,而非重复使用初始值0。错误的offset会导致重复请求同一页数据,进而触发merge后的数据重复。正确的调用示例:fetchMore({ variables: { // 基于已有数据长度计算新的offset offset: data?.AssetData.assets.length || 0, // 保持其他变量与原查询一致 role, version, region, limit: 30 }, // 可配合updateQuery手动合并数据(与typePolicies的merge功能互补) updateQuery: (prevResult, { fetchMoreResult }) => { if (!fetchMoreResult) return prevResult; return { ...prevResult, AssetData: { ...prevResult.AssetData, assets: [...prevResult.AssetData.assets, ...fetchMoreResult.AssetData.assets] } }; } });优化typePolicies的merge逻辑
当前merge函数直接拼接数组,未做去重处理。即使重复请求数据,也会导致缓存中出现重复项。可以在merge中加入去重逻辑:merge(existing = [], incoming: string[], { args }) { const existingItems = new Set(existing); // 过滤掉已存在的项 const newItems = incoming.filter(item => !existingItems.has(item)); return [...existing, ...newItems]; }同时确认
keyFields: []的设置是否符合你的业务场景——该配置会将所有AssetData实例视为同一缓存条目,适合单一分页列表的场景;如果存在多个独立的AssetData列表,需要设置唯一的keyFields来区分。排查useQuery的触发原因
原查询重复发起可能是由于依赖变量(role/version/region)意外变化导致useQuery重新执行。检查这些变量的来源:- 确保变量是稳定的,比如用
useMemo包裹避免不必要的引用变化; - 检查组件是否因其他props变化而重渲染,导致useQuery重复执行初始查询。
- 确保变量是稳定的,比如用
调整fetchPolicy配置
当前fetchPolicy: 'cache-and-network'会在组件挂载时同时请求缓存和网络,而nextFetchPolicy: 'cache-first'仅在后续操作优先使用缓存。但在无限滚动场景下,可尝试调整为:useQuery<AssetsQuery>(assetsQuery, { variables: { /* ... */ }, fetchPolicy: 'cache-first', // 首次加载优先用缓存,避免重复请求 notifyOnNetworkStatusChange: true, // 便于监听网络状态变化 });若需要首次加载最新数据,可保留
cache-and-network,但需确认缓存失效策略不会触发不必要的重新请求。排除InvalidationPolicyCache的干扰
你使用了InvalidationPolicyCache并设置了Asset类型的TTL,可能导致缓存频繁失效,触发原查询重复请求。可以暂时替换为普通的InMemoryCache测试:cache: new InMemoryCache({ typePolicies: { /* 保持原typePolicies配置 */ } }),如果问题消失,说明是缓存失效策略导致的,需要调整
timeToLive或针对分页场景优化失效规则。监听networkStatus排查请求触发源
开启notifyOnNetworkStatusChange: true后,打印networkStatus值,确认每次请求的触发时机:useEffect(() => { console.log('Network status:', networkStatus); }, [networkStatus]);Apollo的
networkStatus枚举值可帮助你区分是初始查询、fetchMore请求还是缓存重新验证请求,进而定位重复请求的来源。
内容的提问来源于stack exchange,提问作者Hima Chitalia

