React-apollo 更新与重新获取 [英] React-apollo update vs refetch

查看:19
本文介绍了React-apollo 更新与重新获取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 react-apollo 并且已经使用了很长时间.对我来说已经是个问题的一件事是

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

解决方案

按照优先顺序,您的选择是:

  1. 什么都不做.对于单个节点的定期更新,只要变异返回变异结果,Apollo 就会自动为你更新缓存.当这无法按预期工作时,通常是因为查询缺少 id(或 _id)字段.当 id 字段不可用时,自定义 dataIdFromObject 函数应该提供给 InMemoryCache 构造函数.当人们将 addTypename 选项设置为 false 时,自动缓存更新也会失败.

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

{const { todos } = cache.readQuery({ 查询:GET_TODOS });cache.writeQuery({查询:GET_TODOS,数据:{ todos: todos.concat([addTodo]) },});}}>{(addTodo) =>(...)}</突变>

  1. 使用 refetchQueries. 除了更新缓存,您还可以提供一个 refetchQueries 函数,它应该返回一个表示要重新获取的查询.这通常不如使用 update 理想,因为它需要对服务器进行一次或多次额外调用.但是,如果突变没有返回足够的信息来手动正确更新缓存,则可能有必要.注意:返回的数组也可能是一个 字符串数组,表示操作名称,尽管没有很好的记录.

[{ 查询: TODOS_QUERY, 变量: { foo: 'BAR' } },]}>{(addTodo) =>(...)}</突变>

  1. 使用refetch.正如您在问题中已经展示的那样,可以使用 Mutation 组件内的 Query 组件提供的 refetch 函数来重新获取该特定查询.如果您的 Mutation 组件已经嵌套在 Query 组件中,这很好,但通常使用 refetchQueries 将是一个更清晰的解决方案,尤其是在多个查询的情况下需要重新获取.

  2. 使用updateQueries.这是一个遗留选项,不再有详细记录,但在添加 update 之前提供了与 update 类似的功能.不应使用它,因为它将来可能会被弃用.

更新:

您还可以以这样的方式设置您的架构,以便可以重新获取查询作为您的突变的一部分.有关详细信息,请参阅这篇文章.

I am using react-apollo and have been for quite some time. 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.

I have got round this by using the refetch prop that is available on a query.

    <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? If you can, is this the standard way to do updates now?

*Using refetchQueries not working

As you can see in the image the console.info() displays that the data.status = "CREATED"; but the request coming back from the mutation directly is data.status = "PICKED"; PICKED is the correct and uptodate information in the DB.

解决方案

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. When this fails to work as expected, it's usually because the query is missing the id (or _id) field. When an id field is not available, a custom dataIdFromObject function should be provided to the InMemoryCache constructor. Automatic cache updates also fail when people set the addTypename option to false.

  2. Use update. The update function will run after your mutation completes, and lets you manipulate the cache directly. 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. 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. Instead of updating the cache, you may also provide a refetchQueries function, which should return an array of objects representing the queries to refetch. This is generally less desirable than using update since it requires one or more additional calls to the server. 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. 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. 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.

  2. Use updateQueries. This is a legacy option that's no longer well-documented, but provided similar functionality to update before update was added. 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.

这篇关于React-apollo 更新与重新获取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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