【问题标题】:Update Apollo GraphQL cache without using refetchQueries?在不使用 refetchQueries 的情况下更新 Apollo GraphQL 缓存?
【发布时间】:2018-05-26 03:23:04
【问题描述】:

我有一个使用 Apollo 客户端(版本 1.x)访问 GraphQL 服务器的 React 应用程序。有一个看起来像这样的服务器架构。

type Query {
  currentShop: Shop
}
type Shop {
  id: ID!
  name: String!
  products: [Product!]!
  ...etc
}

我确实有这样定义的dataIdFromObject

const dataIdFromObject = o => {
  if (o.__typename != null && o.id != null) {
    return `${o.__typename}-${o.id}`
  }
  return null
}

在整个应用程序中,我正在运行查询currentShop 的不同字段。在不同的点上,还有一些突变正在改变 currentShop 并且突变总是返回导致 Shop 类型。但是,与currentShop 无关,因此 Apollo 无法知道如何更新根查询缓存指针。

我已经用CodeSandbox 做了完整的演示来代表这个问题。后端使用Apollo LaunchPad 制作。选择一个不同的分支,等待几秒钟(没有进行优化),它就可以工作了。

“魔法”发生在ShopSelectButton 组件中。如果您注释掉 refetchQueries 行,事情就会被破坏。商店在服务器上被正确选择(并且你在重新加载后看到它),但客户端就像死动物一样。

我的问题是refetchQueries,因为它使代码耦合得太紧了。我不想在应用程序的某个部分使用一个组件来了解任何其他组件及其需求。老实说,重新获取意味着它会绕过整个缓存,并且总是从后端读取,这在大多数情况下是不必要的。

我想知道还有什么其他方法可以解决这个问题。架构是否应该构建得更加无状态,并将状态保留在前端应用程序中?

【问题讨论】:

    标签: javascript graphql apollo react-apollo apollo-client


    【解决方案1】:

    我认为突变应该可以在不重新获取查询的情况下工作。您只需在突变结果正文中添加相关查询中的所有必需数据。

    您是否尝试为 chrome 安装 apollo 客户端开发工具扩展?在那里,您可以轻松查看不同查询中的 currentShop 元素是否通过 typename 和 id 与 Shop 类型相关。 如果是这种情况,apollo 应该在突变后更新。

    要获取正确更新突变结果所需的所有数据,我建议您向应用程序添加片段结构。这意味着所有需要来自商店的数据的组件都有一个定义需求的片段字段。 收集片段并将其添加到突变体中。当然,这样做你在其他组件和突变之间有相同的耦合。

    另一种选择是将 Shop 类型的所有可能数据添加到突变结果中。

    【讨论】:

    • 是的,我不喜欢紧耦合,特别是如果我的应用程序需要模块化到那种程度,它不知道会有什么模块。
    • 另外,我认为您所描述的关系不存在。 currentShop 指向一个特定的 typename:id 并且突然它只在服务器上被改变了。阿波罗无法知道这一点。我尝试使用writeQuery 来更新这个基本上可以工作的指针,但它仍然缺少所有这些查询的所有其他字段。
    • 无论如何,我意识到无状态服务器可能是更好的方法。这是那次尝试的结果。 codesandbox.io/s/ly9j7w1l9
    • 是的,做得很好!注入持有商店ID的商店
    • @FredyC,请将您的解决方案作为答案发布,以便其他人受益。
    猜你喜欢
    • 2018-07-15
    • 2021-05-09
    • 2020-02-14
    • 2020-02-28
    • 2019-12-28
    • 2020-11-17
    • 2015-11-28
    • 2021-03-24
    • 2020-04-24
    相关资源
    最近更新 更多