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

Next.js中Apollo Client fetchMore无法更新数据缓存求助

问题分析与解决方案

1. 先确认后端数据一致性

手动在GraphQL Playground执行创建对话的mutation,紧接着执行GET_CONVERSATION_LIST查询:

  • 如果新对话不在查询结果里,优先排查后端NestJS代码:
    • 检查mutation是否正确提交数据库事务(比如TypeORM事务未完成就返回);
    • 确认列表查询resolver是否存在缓存未更新的情况。

2. 修正Apollo Client的SSR模式配置

当前代码固定ssrMode: true,客户端运行时会导致缓存行为异常,需根据环境自动切换:

function createApolloClient() {
  return new ApolloClient({
    ssrMode: typeof window === 'undefined', // 服务器端为true,客户端自动设为false
    link: createIsomorphLink(),
    cache: new InMemoryCache()
  })
}

3. 优化fetchMore的缓存更新逻辑

直接返回fetchMoreResult会完全覆盖旧数据,建议合并新旧数据并去重,确保缓存正确更新:

fetchMore({
  context: { headers: { authorization: `Bearer ${getCookie("session")}` } },
  updateQuery(prevResult, { fetchMoreResult }) {
    if (!fetchMoreResult) return prevResult;
    
    // 替换为你实际的列表字段名
    const existingIds = prevResult.conversations.map(c => c.id);
    return {
      ...prevResult,
      conversations: [
        ...fetchMoreResult.conversations,
        ...prevResult.conversations.filter(c => !existingIds.includes(c.id))
      ]
    };
  }
})

4. 验证服务器端getServerSideProps查询正确性

在服务器端打印查询结果,确认是否能获取到新对话:

export const getServerSideProps: GetServerSideProps = async (ctx) => {
  const apolloClient = initializeApollo()
  const result = await apolloClient.query({
    query: GET_CONVERSATION_LIST,
    context: { headers: { authorization: `Bearer ${ctx.req.cookies["session"]}` } },
    errorPolicy: "all"
  })
  
  // 打印结果排查问题
  console.log("Server-side conversation data:", result.data);
  
  return {
    props: {
      initialApolloState: apolloClient.cache.extract(),
    }
  }
}
  • 如果服务器端查不到新数据,检查:
    • ctx.req.cookies["session"]是否与客户端创建对话时的会话一致;
    • 后端是否存在会话隔离或权限问题。

5. 修复Apollo缓存合并逻辑

使用深度合并(需安装lodash.merge)避免浅合并导致数据丢失:

import merge from 'lodash/merge';

export function initializeApollo(initialState = null) {
  const _apolloClient = apolloClient ?? createApolloClient()
  if (initialState) {
    const existingCache = _apolloClient.extract()
    const mergedData = merge({}, existingCache, initialState)
    _apolloClient.cache.restore(mergedData)
  }
  if (!apolloClient) apolloClient = _apolloClient
  return _apolloClient
}

6. 可选:调整useQuery的fetchPolicy

如果需要强制客户端每次从服务器拉取最新数据(会影响SSR性能,按需使用):

const { data } = useQuery<GetConversationData>(GET_CONVERSATION_LIST, {
  fetchPolicy: "network-only"
});

内容的提问来源于stack exchange,提问作者Keya Roy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 04:35:55