Apollo Client - 使用对象列表中的缓存结果来响应对单个对象的查询 [英] Apollo Client - using cached results from object list in response to query for single object

查看:15
本文介绍了Apollo Client - 使用对象列表中的缓存结果来响应对单个对象的查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以将 Apollo 客户端配置为从返回项目列表的查询中获取单个缓存的项目,以便在查询单个项目时预取数据?

Is it possible to configure the Apollo Client to fetch a single cached Item from a query that returns a list of Items, in order to prefetch data when querying for a single Item?

架构:

type Item {
  id: ID!
  name: String!
}

type Query {
  items: [Item!]!
  itemById(id: ID!): Item!
}

查询 1:

query HomepageList {
  items {
    id
    name
  }
}

查询 2:

query ItemDetail($id: ID!) {
  itemById(id: $id) {
    id
    name
  }
}

鉴于个别项目的数据已经在缓存中,应该可以使用已经缓存的数据,同时仍然执行提取,以防任何数据发生变化.

Given that the individual Item's data will already be in the cache, it should be possible to use the already cached data whilst still executing a fetch incase any data has changed.

然而,查询并没有使用缓存数据(至少默认情况下),似乎我们需要以某种方式告诉 Apollo 我们知道该 Item 已经在缓存中.

However, the query does not utilise the cached data (by default at least), and it seems that we need to somehow tell Apollo that we know the Item is already in the cache.

非常感谢任何帮助.

推荐答案

此功能存在,但如果您不知道要查找什么,则很难找到.在 Apollo Client v2 中,您正在寻找缓存重定向功能,在 Apollo Client v3 中,这被类型策略/字段读取策略取代 (v3 文档).

This functionality exists, but it's hard to find if you don't know what you're looking for. In Apollo Client v2 you're looking for cache redirect functionality, in Apollo Client v3 this is replaced by type policies / field read policies (v3 docs).

Apollo 不知道"您的 GraphQL 架构,这使得在日常使用中可以轻松设置和使用.然而,这意味着给定一些查询(例如 getBooks),它不知道结果类型将是什么前期.只要启用了 __typename,它就会知道它之后.这是默认行为,是规范化缓存所必需的.

Apollo doesn't 'know' your GraphQL schema and that makes it easy to set up and work with in day-to-day usage. However, this implies that given some query (e.g. getBooks) it doesn't know what the result type is going to be upfront. It does know it afterwards, as long as the __typename's are enabled. This is the default behaviour and is needed for normalized caching.

假设您有一个 getBooks 查询,它获取 Book 的列表.如果在此请求完成后使用 Apollo devtools 检查缓存,您应该使用 Book:123 键在缓存中查找书籍,其中 Book 是类型名和 123 是 ID.如果它存在(并被查询!)id 字段将用作缓存的标识符.如果您的 id 字段有其他名称,您可以使用缓存的 typePolicies 将这个字段通知 Apollo InMemoryCache.

Let's assume you have a getBooks query that fetches a list of Books. If you inspect the cache after this request is finished using Apollo devtools, you should find the books in the cache using the Book:123 key in which Book is the typename and 123 is the id. If it exists (and is queried!) the id field is used as identifier for the cache. If your id field has another name, you can use the typePolicies of the cache to inform Apollo InMemoryCache about this field.

如果您已经设置好并在之后运行 getBook 查询,使用一些 id 作为输入,您将不会获得任何缓存数据.原因如前所述:Apollo 不知道该查询将返回哪种类型.

If you've set this up and you run a getBook query afterwards, using some id as input, you will not get any cached data. The reason is as described before: Apollo doesn't know upfront which type this query is going to return.

因此在 Apollo v2 中,您将使用 cacheRedirect 将 Apollo重定向"到正确的缓存:

So in Apollo v2 you would use a cacheRedirect to 'redirect' Apollo to the right cache:

  cacheRedirects: {
    Query: {
      getBook(_, args, { getCacheKey }) {
        return getCacheKey({
          __typename: 'Book',
          id: args.id,
        });
      }
    },
  },

(args.id 如果您在 typePolicy 中指定了另一个键,则应替换为另一个标识符)

(args.id should be replaced by another identifier if you have specified another key in the typePolicy)

当使用 Apollo v3 时,你需要一个 typepolicy/field read policy:

When using Apollo v3, you need a typepolicy / field read policy:

  typePolicies: {
    Query: {
      fields: {
        getBook(_, { args, toReference }) {
          return toReference({
            __typename: 'Book',
            id: args.id,
          });
        }
      }
    }
  }

这篇关于Apollo Client - 使用对象列表中的缓存结果来响应对单个对象的查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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