【问题标题】:React-apollo update vs refetchReact-apollo 更新与重新获取
【发布时间】:2019-11-19 04:26:20
【问题描述】:

我使用 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 不起作用

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

【问题讨论】:

    标签: javascript reactjs graphql react-apollo


    【解决方案1】:

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

    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。正如您在问题中已经表明的那样,可以使用 Query 组件中的 refetch 函数在您的 Mutation 组件中重新获取该特定查询。如果您的Mutation 组件已经嵌套在Query 组件内,这很好,但通常使用refetchQueries 将是一个更简洁的解决方案,特别是在需要重新获取多个查询时。

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

    更新:

    您还可以设置架构,使查询可以作为突变的一部分重新获取。详情请见this article

    【讨论】:

    • 哦哇...我没有意识到如果您向突变提供查询它会自动更新,它会更新。如果我执行mutation something(){} 没有返回数据,那么对于选项 1。我需要提供一个查询以及我假设的突变?也谢谢你的回复:)
    • 无论如何,您都需要提供某种选择集,除非您的突变只返回一个标量。但是要有效地回答您的问题,是的。请再次记住,答案中概述了此机制的局限性。查看文档中的规范化部分了解更多详细信息。
    • 是的,我相信这将是我的主要问题,mutation returns the mutated result。如果我是正确的,我可以使用InMemoryCache({ dataIdFromObject 手动映射我的所有数据结构我已经更新了我的问题以包含为什么refetchQueries 不起作用的图像。我再次相信它是这种映射。非常感谢您的帮助,伙计。超级有用的答案!!!
    • 哦,我认为这个问题可能是因为我们正在使用graph-lodash 我会玩这个
    • graphql-lodash 是一个实验项目,可能不应该在生产中使用。我无法谈论它将如何与 Apollo 的缓存逻辑交互,但听起来那里有些不协调。很高兴你解决了。
    猜你喜欢
    • 2019-03-14
    • 2019-03-26
    • 2019-04-27
    • 2020-02-04
    • 2019-12-20
    • 2018-12-31
    • 2021-01-16
    • 2019-05-10
    • 2018-09-23
    相关资源
    最近更新 更多