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

GraphQL Mutation后更新Apollo本地缓存:读取无结果,求正确实现

Apollo缓存更新问题排查与修复

问题现状

执行CREATE_POST Mutation成功在数据库创建Post,但在update回调中调用cache.readQuery({ query: GET_POSTS })返回空值,无法完成本地缓存更新。

当前代码片段

Mutation与调用代码

const CREATE_POST = gql`
  mutation createPost($title: String!, $body: String!, $userId: Int!) {
    createPost(title: $title, body: $body, userId: $userId) {
      title
      body
      userId
    }
  }
`;

const [createPost] = useMutation(CREATE_POST);

const variables = { title, body, userId: numbered };
console.log('variables', variables);
createPost({
  variables,
  update(cache) {
    const results = cache.readQuery({ query: GET_POSTS });
    console.log(results);
    // cache.writeQuery({
    //   query: GET_POSTS,
    //   data: {
    //     posts: [...posts, variables],
    //   },
    // });
  },
});

InMemoryCache配置

typePolicies: {
  Query: {
    fields: {
      posts: {
        keyArgs: ['limit'],
        merge: (existing, incoming) => {
          console.log('existing', existing);
          console.log('incoming', incoming);
          const result = [...(existing || []), ...incoming];
          return result;
        },
      },
    },
  },
}

问题分析

当前缓存更新实现不正确,核心问题如下:

  • readQuery未传入匹配变量:你的typePolicies中posts字段的keyArgs设为['limit'],意味着不同limit值的GET_POSTS查询会被缓存为不同条目。如果调用readQuery时未传入与之前执行GET_POSTS时完全一致的variables(比如{ limit: 10 }),会找不到对应缓存数据,返回undefined。
  • 未处理缓存为空的情况:如果GET_POSTS从未被执行过,缓存中原本就没有posts数据,readQuery会返回undefined,后续展开...posts会直接报错。
  • 写入缓存用错数据:注释的writeQuery中用了variables(请求参数)而非Mutation返回的真实Post数据,这会导致缓存数据与数据库实际数据不一致。

修复方案

修改后的update回调代码

createPost({
  variables,
  update(cache, { data }) {
    // 替换为你实际调用GET_POSTS时使用的变量
    const queryVariables = { limit: 10 };
    // 读取缓存,缓存为空时返回默认空数组
    const { posts = [] } = cache.readQuery({
      query: GET_POSTS,
      variables: queryVariables,
    }) || {};

    // 获取Mutation返回的新Post数据
    const newPost = data.createPost;

    // 写入更新后的缓存
    cache.writeQuery({
      query: GET_POSTS,
      variables: queryVariables,
      data: {
        posts: [...posts, newPost],
      },
    });
  },
});

额外注意事项

  • 确保CREATE_POST Mutation返回的字段与GET_POSTS查询返回的Post字段完全一致,否则缓存合并会出现数据缺失。
  • 如果GET_POSTS包含其他影响结果的参数(比如offset),需要将其加入typePolicies的keyArgs数组中,避免不同参数的查询缓存被错误合并。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 05:45:29