Bar*_*art 6 javascript caching apollo react-apollo apollo-client
我之前在Apollo\xe2\x80\x99s 社区聊天中问过这个问题中问过这个问题,但我将其重新发布到这里,因为两周后 \xe2\x80\x99 没有得到答复。
\n这个问题是关于Apollo 3.0引入的新缓存的。此更新弃用了本地查询,转而使用 \xe2\x80\x9ctype 策略\xe2\x80\x9d(或 \xe2\x80\x9cfield 策略\xe2\x80\x9d),其中包括多个用于处理缓存的工具,例如可以为每个 GraphQL 类型定义一个merge函数,以指定传入数据应如何与缓存中的现有数据合并。
我\xe2\x80\x99m 想知道哪些用例更适合该函数,而不是通过或merge编写预先计算的更新值。writeQuerywriteFragment
让\xe2\x80\x99s 说我有一个包含对象的数组,并且该数组是另一种类型的属性。例如:
\ntype Person {\n hobbies: [Hobby!]!\n}\nRun Code Online (Sandbox Code Playgroud)\n该应用程序允许我删除、添加和更新该数组中的元素。应该hobbies使用该merge功能吗?以前,我在本地突变解析器中编写了此逻辑,但这些已被弃用。我可以通过为每个解析器定义一个函数来轻松模仿旧行为,该函数包含添加/删除/更新逻辑,并用于writeFragment存储结果。
我可以看到使用的好处,merge因为(我认为)it\xe2\x80\x99是较低的抽象层,但是它可以在传入数组的情况下使用吗hobbies?据我所知,它的工作方式意味着我们\xe2\x80\x99d 必须通过传入的输入来推断突变的类型。例如:
Hobby,因为其他爱好也可能受到影响,例如由于不重叠的时间限制)。这似乎不如镜像旧方法那么优雅,在旧方法中,在hobbies调用之前计算新值writeFragment新值。
使用有性能优势吗merge?hobbies使用 时,现有的和不受影响的项目是否保留在原处merge,并在使用 时被覆盖writeFragment?假设新计算的数据传递到writeFragment包含一个数组,其中包含未修改元素的浅副本。
非常感谢您为我解决了这个问题!
\n与此同时,我实现了一个类似于Apollo 文档中概述的 \xe2\x80\x99s 的合并函数。此函数尽可能多地重用数组中的项目existing,并从其他位置获取项目incoming。相等性是根据 object 检查的id,它几乎总是存在于我的应用程序中。
这种方法的唯一(次要)缺点似乎是它不能处理数组中的项目被更改的情况,但这种操作是在不返回的单独突变中完成的无论如何,一个数组。
\n为了后人的利益,我的实现如下:
\nimport type { FieldPolicy, Reference } from \'@apollo/client\'\n\n/**\n * Based on example in Apollo docs\n *\n * @see https://www.apollographql.com/docs/react/caching/cache-field-behavior/#merging-arrays-of-non-normalized-objects\n */\nexport const mergeArrayByIdFieldPolicy: FieldPolicy<Reference[]> = {\n // eslint-disable-next-line @typescript-eslint/default-param-last\n merge: (existing = [], incoming = [], { readField, mergeObjects }) => {\n const merged = [...incoming]\n const existingIds = existing.map((item) => readField<UUID>(\'id\', item))\n\n merged.forEach((item, index) => {\n const itemId = readField<UUID>(\'id\', item)\n const existingIndex = existingIds.findIndex((id) => id === itemId)\n if (existingIndex !== -1) {\n merged[index] = mergeObjects(existing[existingIndex], merged[index])\n }\n })\n return merged\n },\n}\nRun Code Online (Sandbox Code Playgroud)\n