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

如何让Apollo Client在ssrMode为true时遵守network-only获取策略?

解决Apollo Client SSR中useSuspenseQuery的缓存与网络请求问题

1. 让服务器端useSuspenseQuery强制走网络或遵守fetchPolicy

针对ssrMode: true的场景

当设置ssrMode: true时,Apollo默认复用服务器端缓存导致后续请求直接读缓存。要强制走网络,可直接在useSuspenseQuery中显式指定策略:

const { data } = useSuspenseQuery(GET_DATA_QUERY, {
  fetchPolicy: 'network-only',
  ssr: true, // 确保查询在SSR阶段执行
});

该配置会跳过缓存强制从网络拉取数据,同时保留SSR阶段的执行逻辑。

针对省略ssrMode的场景

省略ssrMode时的 hydration 错误,根源是跨请求复用了服务器端缓存。解决的核心是为每个请求创建独立的Apollo Client实例,同时搭配指定fetchPolicy:

// 服务器端每个请求调用一次该函数创建Client
function createApolloClient() {
  return new ApolloClient({
    uri: 'YOUR_GRAPHQL_ENDPOINT',
    cache: new InMemoryCache(),
    // 不设置ssrMode,每个请求拥有独立缓存空间
  });
}

// 组件中使用
const { data } = useSuspenseQuery(GET_DATA_QUERY, {
  fetchPolicy: 'network-only',
});

独立实例的缓存相互隔离,不会出现过期缓存复用导致的 hydration 不匹配问题。

2. 客户端修改数据后,确保服务器端后续请求走网络

客户端修改数据后,服务器端要避免返回旧缓存,关键是禁止跨请求复用Apollo Client实例:

  • 坚持为每个HTTP请求创建全新的Client实例,每个实例的缓存都是初始状态,自然会从网络拉取最新数据。
  • 若因特殊场景必须复用Client实例(不推荐),则需在每个请求处理前手动清理缓存:
// 清除指定查询的缓存条目
await apolloClient.cache.evict({ query: GET_DATA_QUERY });
await apolloClient.cache.gc(); // 清理失效缓存

// 或直接重置整个缓存
await apolloClient.cache.reset();

3. 是否需要手动清除缓存?

  • 如果服务器端为每个请求创建独立Apollo Client,无需手动清除缓存,每个实例的缓存都是全新的,天然隔离旧数据。
  • 如果必须复用Client实例,则必须在每个请求处理前手动清理缓存或重置特定查询的缓存条目,否则会出现旧数据复用问题。

内容的提问来源于stack exchange,提问作者Moritz Roessler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:06:01