简体   繁体   English

React-Apollo更新与Refetch

[英]React-apollo update vs refetch

I am using react-apollo and have been for quite some time. 我正在使用react-apollo,已经使用了一段时间。 One thing that has already been a problem for me is the fact that refetch doesn't work when using a mutation This has been a know issue for as long as I have been using the app. 对我来说,已经成为问题的一件事是, 使用变异时refetch无效。事实上,只要我一直在使用该应用程序,这就是一个已知问题。

I have got round this by using the refetch prop that is available on a query. 我已经通过使用查询中可用的refetch prop解决了这个问题。

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

However I am now reading in the documentation that you recieve an update method as part of a mutation and you should use this to update your application after a mutation. 但是,我现在在文档中看到,您将更新方法作为突变的一部分,因此您应该在突变后使用它来更新应用程序。

Can you use the update function to update your UI's data and have it update after finishing a mutation? 您可以使用update功能来更新您的UI数据,并在完成突变后更新它吗? If you can, is this the standard way to do updates now? 如果可以的话,这是现在进行更新的标准方法吗?

*Using refetchQueries not working *使用refetchQueries不起作用

在此处输入图片说明

As you can see in the image the console.info() displays that the data.status = "CREATED"; 如您在图像中看到的, console.info()显示data.status = "CREATED"; but the request coming back from the mutation directly is data.status = "PICKED"; 但直接从突变返回的请求是data.status = "PICKED"; PICKED is the correct and uptodate information in the DB. PICKED是数据库中正确且最新的信息。

In order of preference, your options are: 按照优先顺序,您可以选择:

  1. Do nothing . 什么都不做 For regular updates to an individual node, as long as the mutation returns the mutated result, Apollo will update the cache automatically for you. 对于单个节点的常规更新,只要变异返回变异结果,Apollo都会为您自动更新缓存。 When this fails to work as expected, it's usually because the query is missing the id (or _id ) field. 当此操作无法按预期工作时,通常是因为查询缺少id (或_id )字段。 When an id field is not available, a custom dataIdFromObject function should be provided to the InMemoryCache constructor. id字段不可用时,应将自定义dataIdFromObject函数提供给InMemoryCache构造函数。 Automatic cache updates also fail when people set the addTypename option to false . 当人们将addTypename选项设置为false时,自动高速缓存更新也会失败。

  2. Use update . 使用update The update function will run after your mutation completes, and lets you manipulate the cache directly. update功能将在您的变异完成后运行,并让您直接操作缓存。 This is necessary if the mutation affects a field returning a list of nodes. 如果该突变影响返回一个节点列表的字段,则这是必需的。 Unlike simple updates, Apollo has no way to infer whether the list should be updated (and how) following the mutation, so we have to directly update the cache ourselves. 与简单更新不同,Apollo无法推断出突变后是否应该更新列表(以及如何更新),因此我们必须自己直接更新缓存。 This is typically necessary following create and delete mutations, but may also be needed after an update mutation if the updated node should be added or removed to some field that returns a list. 在创建和删除突变之后,这通常是必需的,但在更新突变之后也可能需要(如果应将更新的节点添加或删除到返回列表的某个字段中)。 The docs go into a good deal of detail explaining how to do this. 文档详细介绍了如何执行此操作。

<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. Use refetchQueries . 使用refetchQueries Instead of updating the cache, you may also provide a refetchQueries function, which should return an array of objects representing the queries to refetch. 除了更新缓存之外,您还可以提供refetchQueries函数,该函数应返回一个对象数组,该对象表示要进行查询的查询。 This is generally less desirable than using update since it requires one or more additional calls to the server. 与使用update相比,这通常不那么理想,因为它需要对服务器进行一个或多个其他调用。 However, it may be necessary if the mutation does not return enough information to correctly update the cache manually. 但是,如果突变没有返回足够的信息来手动正确更新缓存,则可能是必要的。 NOTE: The returned array may also be an array of strings representing operation names, though this is not well documented. 注意:返回的数组也可能是表示操作名称的字符串数组 ,尽管没有充分说明。
<Mutation
  mutation={ADD_TODO}
  refetchQueries={() => [
    { query: TODOS_QUERY, variables: { foo: 'BAR' } },
  ]}
>
  {(addTodo) =>(...)}
</Mutation>
  1. Use refetch . 使用refetch As you already showed in your question, it's possible to use the refetch function provided by a Query component inside your Mutation component to refetch that specific query. 正如您在问题中已经显示的那样,可以使用Mutation组件内部的Query组件提供的refetch函数来重新获取该特定查询。 This is fine if your Mutation component is already nested inside the Query component, but generally using refetchQueries will be a cleaner solution, particularly if multiple queries need to be refetched. 如果您的Mutation组件已经嵌套在Query组件中,那refetchQueries ,但是通常使用refetchQueries是一种更清洁的解决方案,尤其是在需要重新查询多个查询的情况下。

  2. Use updateQueries . 使用updateQueries This is a legacy option that's no longer well-documented, but provided similar functionality to update before update was added. 这是一个遗留选项,已不再有据可查,但提供了类似的功能,可以在添加update之前进行update It should not be used as it may be deprecated in the future. 不应使用它,因为将来可能会不推荐使用。

UPDATE: 更新:

You may also set up your schema in such a way that queries can be refetched as part of your mutation. 您还可以通过以下方式设置架构:查询可以作为您的突变的一部分重新获取。 See this article for more details. 有关更多详细信息,请参见本文

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM