微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

具有命名空间查询的Apollo Client 3.0缓存

如何解决具有命名空间查询的Apollo Client 3.0缓存

我对如何配合阿波罗客户端缓存以及我们组织查询的特定方式存在一些疑问。

因此,组织查询的方式是将查询分组在同一名称空间下的同一资源上。例如。我们有两个资源usersaccounts,我们的查询如下所示。

type Query {
  user: UserQueries
  account: AccountQueries
}

type UserQueries {
  all: [User!]!
  byId(id: ID!): User
}

type AccountQueries {
  all: [Account!]!
  byId(id: ID!): Account
}

type User {...}
type Account {...}

由于两种Queries都没有提供ID字段,因此认情况下UserQueries下第二个查询的响应将替换缓存中第一个查询的数据,即首先我创建一个{{1 }}查询,然后取回一些存储在all字段下的缓存中的数据。然后,如果我进行user查询,则byId下缓存中的数据将被新数据替换。

有关此过程的一些问题:

  1. 我注意到,即使将user数据替换为all数据之后,以前缓存的用户(规范化用户)在缓存中仍然可用,因为我认为这些用户会被垃圾回收因为引用丢失了。垃圾收集器是否不立即进行垃圾收集,而是以一定的节奏运行?还是我完全误解了gc的工作原理?
  2. 除了为查询类型生成唯一ID byId之外,还有其他方法可以保留两个响应吗?
  3. 像这样的名称空间查询甚至是个好主意吗?

谢谢大家!

解决方法

如您所知,由于缓存不知道该查询在技术上总是返回相同的对象,因此结果将被其他查询覆盖。

对此有两种解决方案:

您已经确定了第一个对象:为这些对象提供一个静态ID字段。这很丑。第二个方法是为docs中讨论的这些查询字段编写merge函数。我认为名称空间通常并不是一个坏主意,但是正如您所看到的,您必须为架构中的 any 实体类型编写此合并函数。因此,我建议您谨慎使用命名空间。

垃圾收集器在Apollo 3中也进行了一些更新。现在可以对其进行自定义并随时运行。您可以阅读有关GC here的更多信息。不再引用的对象可能会在缓存中保留一段时间。文档似乎没有指定GC的运行时间。可以通过调用client.gc()来手动运行它。

,

实际上,在Apollo 3中使用命名空间查询的正确方法是将keyFields设置为空数组。 当您这样做时,您会向Apollo显示没有要合并的ID,因此所有内容都应合并在同一缓存键中。 您不必为此编写合并功能。

通过typePolicies配置中的InMemoryCache选项进行配置

const apolloClient = new ApolloClient({
  cache: new InMemoryCache({
    typePolicies: {
      UserQueries: {
        keyFields: [],},AccountQueries: {
        keyFields: [],}),});

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。