React-Apollo更新与Refetch

时间:2019-07-09 15:03:52

标签: javascript reactjs graphql react-apollo

我正在使用react-apollo,已经使用了一段时间。对我来说,已经成为问题的一件事是,refetch doesn't work when using a mutation自从我使用该应用程序以来一直是一个已知问题。

我通过使用查询中可用的refetch道具解决了这个问题。

    <Query query={query} fetchPolicy={fetchPolicy} {...props}>
      {({ loading, data, error, refetch }) => {
     ... pass down to mutation
    </Query>

不过,我现在正在读您收到的documentation 一种更新方法,作为突变的一部分,您应该使用此方法在突变后更新应用程序。

您可以使用update函数来更新您的UI数据,并在完成突变后更新它吗?如果可以的话,这是现在进行更新的标准方法吗?

*使用refetchQueries不起作用

enter image description here

如您在图像中所见,console.info()显示data.status = "CREATED";,但是直接从突变返回的请求是data.status = "PICKED"; PICKED是正确的最新信息在数据库中。

1 个答案:

答案 0 :(得分:2)

按照优先顺序,您可以选择以下选项:

  1. 不执行任何操作。对于单个节点的常规更新,只要变异返回变异结果,Apollo都会为您自动更新缓存。如果此操作无法正常工作,通常是因为查询缺少id(或_id)字段。当id字段不可用时,应向InMemoryCache构造函数提供自定义的dataIdFromObject函数。当人们将addTypename选项设置为false时,自动缓存更新也会失败。

  2. 使用update update函数将在您的变异完成后运行,并让您直接操作缓存。如果该突变影响返回一个节点列表的字段,则这是必需的。与简单更新不同,Apollo无法推断出突变后是否应该更新列表(以及如何更新),因此我们必须自己直接更新缓存。在创建和删除突变之后,这通常是必需的,但在更新突变之后也可能需要(如果应将更新的节点添加或删除到返回列表的某个字段中)。 docs详细介绍了如何执行此操作。

<Mutation
  mutation={ADD_TODO}
  update={(cache, { data: { addTodo } }) => {
    const { todos } = cache.readQuery({ query: GET_TODOS });
    cache.writeQuery({
      query: GET_TODOS,
      data: { todos: todos.concat([addTodo]) },
    });
  }}
>
  {(addTodo) =>(...)}
</Mutation>
  1. 使用refetchQueries除了更新缓存之外,您还可以提供一个refetchQueries函数,该函数应返回表示要重新获取的查询的对象数组。通常,这不如使用update理想,因为它需要对服务器进行一个或多个其他调用。但是,如果突变没有返回足够的信息来手动正确更新缓存,则可能是必要的。注意:返回的数组也可能是表示操作名称的array of strings,尽管没有充分记录。
<Mutation
  mutation={ADD_TODO}
  refetchQueries={() => [
    { query: TODOS_QUERY, variables: { foo: 'BAR' } },
  ]}
>
  {(addTodo) =>(...)}
</Mutation>
  1. 使用refetch 。正如您在问题中已经显示的那样,可以使用refetch组件内部的Query组件提供的Mutation函数来重新获取该特定查询。如果您的Mutation组件已经嵌套在Query组件中,那很好,但是通常使用refetchQueries是一个更干净的解决方案,尤其是在需要重新查询多个查询的情况下。

  2. 使用updateQueries 。这是一个遗留选项,已不再有据可查,但在添加update之前提供了与update类似的功能。不应使用它,因为将来可能会不推荐使用它。