突变后自动更新 apollo 客户端缓存,不影响现有查询 [英] Auto-update of apollo client cache after mutation not affecting existing queries

查看:53
本文介绍了突变后自动更新 apollo 客户端缓存,不影响现有查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个突变(UploadTransaction)返回名为 Transaction 的特定对象的特定列表.

I have a mutation (UploadTransaction) returning certain list of certain object named Transaction.

#import "TransactionFields.gql" 
mutation UploadTransaction($files: [Upload!]!) {
  uploadFile(files: $files){
    transactions {
      ...TransactionFields
    }
  }
}

从后端(石墨烯)返回的事务具有 id 和 typename 字段.因此它应该自动更新缓存中的事务.在 Apollo 的 chrome 开发工具中,我可以看到新的交易:

Transaction returned from backend (graphene) has id and typename field. Hence it should automatically update Transaction in the cache. In chrome dev tools for Apollo, I can see new transactions:

我还有一个查询 GetTransactions 来获取所有 Transaction 对象.

I also have a query GetTransactions fetching all Transaction objects.

#import "TransactionFields.gql"
query GetTransactions {
  transactions {
    ...TransactionFields
  }
}

但是我没有看到查询返回新添加的事务.在初始加载期间,Apollo 客户端加载了 292 个事务,显示在 ROOT_QUERY 下.它不断返回相同的 292 笔交易.UploadTransaction 突变在开发工具的缓存中添加事务"类型的新对象,而不会影响开发工具中的 ROOT_QUERY 或我在代码中的查询.

However I don't see newly added Transaction being returned by the query. During initial load, Apollo client loaded 292 transactions which it shows under ROOT_QUERY. It keeps returning same 292 transactions. UploadTransaction mutation add new object of type "Transaction" in cache in dev-tools without affecting ROOT_QUERY in dev-tools or my query in code.

TransactionFields.gql 是

TransactionFields.gql is

fragment TransactionFields on Transaction {
    id
    timestamp
    description
    amount
    category {
      id
      name
    }
    currency
}

知道我做错了什么吗?我是 apollo 客户端和 graphql 的新手

Any idea what am I doing wrong? I am new to apollo client and graphql

推荐答案

来自 文档:

如果突变更新了单个现有实体,则 Apollo 客户端可以在突变返回时自动更新其缓存中该实体的值.为此,变更必须返回修改实体的 id,以及修改字段的值.方便的是,在 Apollo Client 中,默认情况下突变会这样做......

If a mutation updates a single existing entity, Apollo Client can automatically update that entity's value in its cache when the mutation returns. To do so, the mutation must return the id of the modified entity, along with the values of the fields that were modified. Conveniently, mutations do this by default in Apollo Client...

如果变异修改了多个实体,或者如果它创建或删除实体,Apollo 客户端缓存不会自动更新以反映变异的结果.解决这样,您对 useMutation 的调用可以包含一个更新函数.

If a mutation modifies multiple entities, or if it creates or deletes entities, the Apollo Client cache is not automatically updated to reflect the result of the mutation. To resolve this, your call to useMutation can include an update function.

如果您的查询返回实体列表(例如,用户),然后创建或删除用户,Apollo 无法知道该列表应该更新以反映您的突变.原因有两个

If you have a query that returns a list of entities (for example, users) and then create or delete a user, Apollo has no way of knowing that the list should be updated to reflect your mutation. The reason for this is two fold

  • Apollo 无法知道突变实际上在做什么.它只知道您正在请求哪些字段以及您传递这些字段的参数是什么.我们可能会假设包含插入"之类的词的突变会发生.或创造"正在后端插入一些东西,但这不是给定的.
  • 无法知道插入、删除或更新用户应该更新特定查询.您的查询可能针对名为Bob"的所有用户.-- 如果您创建名为Susan"的用户,则不应更新查询以反映该添加.同样,如果变更更新了用户,则查询可能需要更新以反映更改.是否应该最终归结为只有您的服务器知道的业务规则.
  • There's no way for Apollo to know what a mutation is actually doing. All it knows is what fields you are requesting and what arguments you are passing those fields. We might assume that a mutation that includes words like "insert" or "create" is inserting something on the backend but that's not a given.
  • There's no way to know that inserting, deleting or updating a user should update a particular query. Your query might be for all users with the name "Bob" -- if you create a user with the name "Susan", the query shouldn't be updated to reflect that addition. Similarly, if a mutation updates a user, the query might need to be updated to reflect the change. Whether it should or not ultimately boils down to business rules that only your server knows about.

因此,为了更新缓存,您有两个选择:

So, in order to update the cache, you have two options:

  • 触发相关查询的重新获取.您可以通过将 refetchQueries 选项传递给您的 useMutation 钩子或通过 在这些查询上手动调用refetch.由于这需要向您的服务器发送一个或多个额外请求,因此它是较慢且成本较高的选项,但在 A) 您不想将一堆业务逻辑注入客户端或 B) 更新到缓存复杂而广泛.
  • 为您的 useMutation 钩子提供一个 update 函数,它告诉 Apollo 如何根据突变的结果更新缓存.这可以避免您发出任何其他请求,但确实意味着您必须在服务器和客户端之间复制一些业务逻辑.
  • Trigger a refetch of the relevant queries. You can do this by either passing a refetchQueries option to your useMutation hook, or by manually calling refetch on those queries. Since this requires one or more additional requests to your server, it's the slower and more expensive option but can be the right option when A) you don't want to inject a bunch of business logic into your client or B) the updates to the cache are complicated and extensive.
  • Provide an update function to your useMutation hook that tells Apollo how to update the cache based on the results of the mutation. This saves you from making any additional requests, but does mean you have to duplicate some business logic between your server and your client.

使用文档中的 update 示例:

The example of using update from the docs:

update (cache, { data: { addTodo } }) {
  const { todos } = cache.readQuery({ query: GET_TODOS });
  cache.writeQuery({
    query: GET_TODOS,
    data: { todos: todos.concat([addTodo]) },
  });
}

阅读文档了解更多详情.

Read the docs for additional details.

这篇关于突变后自动更新 apollo 客户端缓存,不影响现有查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆