Graphql 创建对象后更新Apollo缓存

Graphql 创建对象后更新Apollo缓存,graphql,apollo,react-apollo,apollo-client,Graphql,Apollo,React Apollo,Apollo Client,在一次变异后,更新阿波罗号有哪些不同的方法,我可以看到: 阿波罗自动执行的任务 仅对现有对象进行单个更新 需要一个唯一标识每个对象的id字段,或者缓存必须配置一个提供唯一标识符的dataIdFromObject函数 “手动”缓存更新通过 创建、删除或更新多个对象时需要 涉及调用cache.writeQuery,详细信息包括应影响哪个查询以及应如何更改缓存 将refetchQueries选项传递给useCommutation钩子 调用代码指出哪些查询应该从API中重新获取,Apollo进

在一次变异后,更新阿波罗号有哪些不同的方法,我可以看到:

  • 阿波罗自动执行的任务
    • 仅对现有对象进行单个更新
    • 需要一个唯一标识每个对象的
      id
      字段,或者缓存必须配置一个提供唯一标识符的
      dataIdFromObject
      函数
  • “手动”缓存更新通过
    • 创建、删除或更新多个对象时需要
    • 涉及调用
      cache.writeQuery
      ,详细信息包括应影响哪个查询以及应如何更改缓存
  • refetchQueries
    选项传递给
    useCommutation
    钩子
    • 调用代码指出哪些查询应该从API中重新获取,Apollo进行获取,结果替换给定查询缓存中的任何内容
  • 有没有其他我错过的方法,或者我是否误解了上述方法

    我很困惑,因为我一直在阅读一个项目的代码,该项目使用Apollo进行所有类型的突变,包括创建和删除,但我没有看到任何对
    cache.writeQuery
    的调用,也没有使用
    refetchQueries
    。在创建和删除缓存后,如果没有这两个选项,缓存如何更新

    根据我对Apollo有限的经验,在创建或删除对象后,缓存不会自动更新,即使我定义了
    dataIdFromObject
    。我必须通过编写更新函数来更新缓存


    所以我想知道我是否错过了一些秘密配置,让Apollo为我处理它。

    创建或删除节点并让Apollo自动更新缓存以反映更改的唯一方法是返回包含更新列表字段的任何字段的父字段。例如,假设我们有这样一个模式:

    type Query {
      me: User
    }
    
    type User {
      id: ID!
      posts: [Post!]!
    }
    
    type Post {
      id: ID!
      body: String!
    }
    
    按照惯例,如果我们有一个变异来添加一个新帖子,变异字段将返回创建的帖子

    type Mutation {
      writePost(body: String!): Post!
    }
    
    但是,我们可以让它返回登录用户(与
    me
    字段返回的内容相同):

    通过这样做,我们使客户机能够进行如下查询:

    mutation WritePost($body: String!){
      writePost(body: $body) {
        id
        posts {
          id
          body
        }
      }
    }
    
    在这里,Apollo不仅会为所有返回的帖子创建或更新缓存,还会更新返回的用户对象,包括帖子列表

    那么,为什么不经常这样做呢?为什么阿波罗的文档建议在添加或删除节点时使用
    writeQuery

    当您的模式很简单并且使用的数据量相对较少时,上述方法可以很好地工作。但是,在处理更多数据后,返回整个父节点(包括其所有关系)的速度会明显变慢,并且会占用更多资源。此外,在许多应用程序中,一次变异可能会影响缓存中的多个查询。同一节点可以由模式中任意数量的字段返回,甚至同一字段也可以是使用不同过滤器、排序参数等的许多不同查询的一部分


    这些因素使得您不太可能希望在生产中实现此模式,但在某些用例中,它可能是一个有效的选项。

    如果我们讨论的是更新缓存中已存在的项,那么,不,如果项目具有唯一的
    id
    \u id
    字段,或者提供自定义的
    dataIdFromObject
    实现,则无需执行任何额外操作。有很多方法可以搞乱客户机配置,但如果不查看代码,就不可能确切知道出了什么问题。你应该在没有发生这种情况的地方提供一组代码,否则这个问题的答案就是简单的“否”。相关的:嘿,谢谢你的评论。我的问题实际上是关于对象创建,而不是缓存中已有的项。如果没有
    cache.writeQuery
    refetchQueries
    ,缓存如何知道对象创建?对不起,我误解了你的问题。但是,您的断言通常仍然是正确的——创建的项目不会插入缓存中的任何列表,因为Apollo根据业务逻辑不知道它是否属于任何现有列表。我能想象的唯一例外是,如果对象创建变异返回相关列表的父字段。同样,如果有一些代码不是这样运行的,那么最好共享它。我认为父字段就是答案——它与我在对象创建后在API响应中看到的一致。非常感谢。如果你想补充一个简单解释问题的答案,我很乐意接受。我无法给出一个简单的例子,因为我有一个很大的现有代码库,显示了良好的行为,而不是糟糕的行为……它只是没有按照我阅读Apollo文档所期望的方式编写。感谢“为什么”部分-非常有用!
    mutation WritePost($body: String!){
      writePost(body: $body) {
        id
        posts {
          id
          body
        }
      }
    }