You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apollo Client fetchMore缓存已更新,但useQuery返回数据未更新

问题分析与解决方案

核心问题

你设置的fetchPolicy: 'network-only'是导致useQuery返回的data不更新的关键原因。这个策略会强制useQuery始终从网络获取初始的第一页数据,完全绕过缓存——即使你已经通过fetchMore将新数据合并到缓存中,组件也不会读取缓存里的合并结果。

修复步骤

1. 修改查询的获取策略

将useQuery的fetchPolicy改为cache-and-network或cache-first:

  • cache-and-network:首次加载时同时请求网络和读取缓存(若存在),后续缓存更新会立即触发组件渲染,同时后台会同步更新缓存(适合需要数据相对实时的场景)。
  • cache-first:优先从缓存读取数据,仅当缓存无对应数据时才发起网络请求(适合分页数据不需要实时刷新的场景)。

修改后的useQuery代码:

const { loading, data, fetchMore, refetch, variables: originalVariables } = useQuery<PostsQuery>(ALL_POSTS_QUERY, {
  variables: {
    input: {
      type: PostType.SOMETHING,
    },
  },
  fetchPolicy: 'cache-and-network', // 替换原有的network-only
  notifyOnNetworkStatusChange: true,
});

2. 合并主查询的变量到fetchMore请求中

你的主查询包含type: PostType.SOMETHING参数,fetchMore时如果只传递startKey,可能导致服务器返回不符合筛选条件的数据。需要将主查询的变量与分页变量合并:

const fetchMorePostsHandler = async () => {
  if (!postsLastKey) {
    return;
  }

  await fetchMore({
    variables: {
      input: {
        ...originalVariables.input, // 继承主查询的筛选参数
        startKey: postsLastKey,
      },
    },
  });
}, [postsLastKey, fetchMore, originalVariables]);

3. 验证merge函数的正确性

确认fetchMore返回的incoming数据结构与你的合并逻辑匹配。如果你的ALL_POSTS_QUERY返回结构为{ posts: Post[] },当前的merge逻辑是正确的;若返回结构不同,需调整incoming的取值路径。

原理说明

当使用缓存相关的fetchPolicy时,Apollo Client会监听缓存中Query.posts字段的变化。fetchMore执行后,merge函数将新数据合并到缓存,Apollo会自动通知useQuery订阅的组件,使其获取更新后的缓存数据并重新渲染。

内容的提问来源于stack exchange,提问作者Stephen Fong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 05:54:52