在不使用 refetchQueries 的情况下更新 Apollo GraphQL 缓存? [英] Update Apollo GraphQL cache without using refetchQueries?

查看:28
本文介绍了在不使用 refetchQueries 的情况下更新 Apollo GraphQL 缓存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a React app accessing GraphQL server with the Apollo Client (version 1.x). There is a server schema that looks like this.

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

我确实有这样定义的 dataIdFromObject.

I do have dataIdFromObject defined like this.

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

在整个应用程序中,我正在运行查询,询问 currentShop 的不同字段.在不同的地方,也有改变 currentShop 的突变,并且突变总是返回结果 Shop 类型.但是,与 currentShop 没有关系,因此 Apollo 无法知道如何更新根查询缓存指针.

Throughout the app, I am running queries asking for different fields of currentShop. At various points there are also mutations that are changing the currentShop and the mutation is always returning resulting Shop type. However, there is no relation to the currentShop so Apollo cannot know how to update root query cache pointer.

我已经用 代码沙盒.后端由 Apollo LaunchPad 制成.选择一个不同的分支,等待几秒钟(不打扰优化)并且它有效.

I've made fully working demo representing the issue with CodeSandbox. The backend is made with Apollo LaunchPad. Picking a different branch, waiting couple seconds (did not bother with optimizations) and it works.

魔法"发生在 ShopSelectButton 组件中.如果您注释掉 refetchQueries 行,事情就会被破坏.在服务器上正确选择了商店(重新加载后您会看到它),但客户端表现得像死动物.

The "magic" is happening in the ShopSelectButton component. If you comment out refetchQueries line, things get broken. The shop is correctly selected on the server (and you see it after reload), but client acts like a dead animal.

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

My problem is with refetchQueries as it makes code too tightly couple. I don't want to have a component in one part of the app to know about any other component and their needs. Also honestly, refetching means it goes around whole caching and it always reads from backend which is unnecessary in most cases.

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

I am wondering what are other approaches to this. Should the schema be built more stateless and keep the state in the frontend app instead?

推荐答案

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

I think the mutation should work without refetching the queries. You just need to add all the required data from the related queries in the mutation result body.

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

Did you try to install the apollo client development tool extension for chrome? There you could easily see if the currentShop element in the different queries is related via the typename and id to a Shop type. If this is the case apollo should update after the mutation.

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

To get all required data for the mutation result to update correctly i suggest you add a fragments structure to your app. Meaning that all components which need data from the shop have a fragments field defining the requirements. The fragments are collected and added to the mutation body. Of course doing this you have the same coupling between the other components and the mutation.

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

Another option would be to add all possible data of the Shop type to the result of the mutation.

这篇关于在不使用 refetchQueries 的情况下更新 Apollo GraphQL 缓存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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