如何使用 Apollo GraphQL Cache 嗨翻全场 🎉🎈
大家好,我是 apollo-cache-inmemory,也就是 Apollo Cache。我是 Apollo Client 中缓存的默认实现。那么,让我来解释一下我们为什么在这里!
我会随时帮助你访问和操作缓存。你执行了数据变更吗?别担心!我可以帮你更新缓存。对了,Redux 的开发者确实很棒,但你可能不再需要用它存储数据了🤷♂。让我来……
呃……谢谢 Apollo Cache 的介绍,不过我想我会继续做下去。
好吧,我第一次尝试 Apollo Cache 的时候,感觉完全摸不着头脑。它的用例太多了,我肯定会迷失方向。再加上其他一些__typename乱七八糟的东西,就更让人困惑了。所以我决定好好研究一下 Apollo Cache。事情是这样的:
首先,你得邀请 Apollo Cache 加入你的团队:
npm install apollo-cache-inmemory --save
现在,Apollo Cache它就能立刻引爆全场。只需将其引入 Apollo Client(Apollo Client 对缓存情有独钟),然后就大功告成了!
const cache = new InMemoryCache();
const client = new ApolloClient({
link: new HttpLink(),
cache
});
但我们希望它能做更多的事情。所以,请让它理解你们的党规,以便它能按照你们的意愿运行。比如这样code of conduct?我们会在构造函数中提供行为准则。顺便说一句,这完全是可选的。好了,开始吧!
行为守则:
addTypename:一个布尔值,用于指定是否将 __typename 添加到文档中。(默认为 true)。稍后会详细介绍。
`dataIdFromObject`:缓存会在将数据保存到 store 之前对其进行规范化处理。这是一个接收数据对象并返回唯一 ID 的函数。稍后会详细介绍它的用法。
fragmentMatcher: Apollo Cache 默认使用启发式片段匹配器。如果您计划在联合体和接口上使用片段,则需要告知 Apollo Cache 此项设置,这有点奇怪。
cacheRedirects:有时,我们会请求 Apollo Cache 存储中已存在的数据,但该数据位于不同的资源键下。通过 cacheRedirects,我们可以告诉 Apollo Cache 在哪里查找已存在的数据。
Apollo Cache 在派对上迅速走红。所有派对参与者(你可以把他们想象成组件)都在与缓存进行交互。我们玩的是 React 和 Act 🧐,缓存里存储着所有我们可以操作的事件以及每个团队的得分。而且我必须说,它的表现非常出色。Apollo Cache 通过以下三点实现了数据的快速存储和检索——
- 将数据拆分成单个对象
- 为每个对象创建一个唯一标识符
- 将数据存储在扁平化的数据结构中
它使用了行为准则中的`addTypename`和`dataIdFromObject`函数来实现这一点。通常,缓存会使用数据中找到的 `id`id和` id` 字段来创建唯一标识符。如果数据中没有提供 `id`,它将使用 `id` 字段作为键。`dataIdFromObject`函数指示缓存使用数据中的特定字段作为唯一标识符,以便之后在与 Apollo 缓存的任何交互(查询)中引用它。_id__typename__typename
我知道这有点让人困惑。所以,我们来详细讨论一下:
首先,缓存是如何记住所有信息的?简单来说,Apollo 缓存会记住你与它的交互方式。缓存将此称为查询路径。
query {
Events (category = 'happy') {
name
}
}
对于上述查询,缓存将创建如下查询路径:RootQuery -> Events(category = 'happy') -> name。它假定每个查询路径都指向一个唯一的资源。因此,下次有人向缓存提出相同的查询时,它就能立即给出答案。例如,一位访客向 Apollo 缓存询问了团队的得分以及“happy”类别下的活动列表。
query {
Score(team = 'A') {
points
}
Events (category = 'happy') {
name
}
}
缓存已经知道事件列表,因为之前有人已经查询过。所以它立即做出了响应。真快!
缓存会尽力记住信息。但有时,查询路径不够清晰。例如,以下是其他两位访客提出的问题:
访客A:嗨,Apollo Cache。你能告诉我“跳舞”类别下的活动吗?
访客B:Cache,你能告诉我第二类活动吗?(这里类别是通过ID来引用的)
现在,id = 2(或第二类)的事件实际上属于“跳舞”类别。缓存是如何看待这些请求的呢?
// 1st Request
query {
Event (category = 'dancing') {
name
}
}
// 2nd Request
query {
Event (id = 2) {
name
}
}
这里,缓存并不知道这两个请求指向的是同一个结果。正常情况下,缓存会获取该数据并将其保存两次。此时,缓存能够通过dataIdFromObject规则来判断这些请求的真正含义。
这是怎么做到的呢?这需要我们稍加引导。因此,dataIdFromObject我们需要为任何需要查询的对象指定一个唯一标识符。这里,我们需要注意不要使用原始 ID(SQL 主键)作为唯一标识符,因为 id = 5 既可以代表一个事件,也可以代表一个访客。我们需要结合使用 `id = 5` 和 `id = 5`。因此,__typename像 `id = 5` 这样的标识符Event:5仅代表 id = 5 的事件数据,而Guest:5`id = 5` 仅代表 id = 5 的访客数据。
如果舞蹈类别中的活动名称从“bachata”更改为“salsa”,则以上两个查询的答案都会更新。简单又方便!
阿波罗缓存还有很多其他妙招。我们下次再讨论吧!
感谢推特用户@DrunkBB8提供原图。
文章来源:https://dev.to/akshar07/how-to-rock-the-party-with-apollo-graphql-cache-361l



