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

查看:153
本文介绍了变异后不影响现有查询的自动更新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字段.因此,它应该自动更新缓存中的Transaction.在用于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 Client可以自动更新其实体在其缓存中的值.为此,变异必须返回修改后的实体的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...

如果某个突变修改了多个实体,或者它创建或删除了实体,则 not 不会自动更新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

  • 阿波罗无法知道某个突变实际上在做什么.它所知道的就是您要请求的字段以及传递这些字段的参数.我们可以假设包括诸如插入"之类的词的突变被称为插入".或创建"在后端插入一些东西,但这不是给定的.
  • 没有办法知道插入,删除或更新用户应该更新特定查询.您的查询可能针对名称为"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:

  • 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的示例:

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天全站免登陆