突变后不影响现有查询的自动更新apollo客户端缓存

时间:2020-02-23 08:04:30

标签: graphql react-apollo apollo-client

我有一个变异(UploadTransaction),它返回某些名为Transaction的对象的某些列表。

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

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

enter image description here

我还有一个查询GetTransactions,可获取所有Transaction对象。

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

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

enter image description here

TransactionFields.gql是

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

知道我在做什么错吗?我是apollo client和graphql的新手

1 个答案:

答案 0 :(得分:5)

来自docs

如果变异更新单个现有实体,则当变异返回时,Apollo Client可以自动更新其缓存中该实体的值。为此,变异必须返回修改后的实体的ID,以及修改后的字段的值。方便地,默认情况下,变异是在Apollo Client中执行的。

如果某个变异修改了多个实体,或者它创建或删除了实体,则会自动更新Apollo客户端缓存以反映变异的结果。为此,您对useMutation的调用可以包含一个更新功能。

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

  • 阿波罗(Apollo)无法知道突变实际上在做什么。它所知道的就是您要请求的字段以及传递这些字段的参数。我们可能会假设一个包含“插入”或“创建”之类的词的突变正在后端插入某些东西,但这不是给定的。
  • 无法知道插入,删除或更新用户应该更新特定查询。您的查询可能针对所有名称为“ Bob”的用户-如果您创建的名称为“ Susan”的用户,则不应更新查询以反映该添加。同样,如果突变更新了用户,则需要更新查询可能以反映更改。最终是否应该归结为只有您的服务器知道的业务规则。

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

  • 触发相关查询的重新提取。您可以通过将refetchQueries选项传递到useMutation挂钩或通过manually calling refetch on those queries来实现。由于这需要向您的服务器发送一个或多个其他请求,因此这是较慢且昂贵的选择,但在以下情况下可能是正确的选择:A)您不想将大量业务逻辑注入客户端或B)更新服务器缓存复杂且范围广泛。
  • 为您的update钩子提供一个useMutation函数,该函数告诉Apollo 如何根据突变结果更新缓存。这样可以避免您发出任何其他请求,但这确实意味着您必须在服务器和客户端之间重复一些业务逻辑。

在文档中使用update的示例:

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

阅读文档以获取更多详细信息。