为什么 GraphQL 片段在查询中需要 __typename?

Why do GraphQL fragments need __typename in queries?

我找不到或我在错误的地方查找有关如何匹配片段的任何文档。当我使用香草 Apollo 客户端时,如果我在使用片段时关闭 addTypename 选项,我会收到警告 heuristic fragment matching going on!,如果我添加它,它就会消失,但我的响应包含许多 __typename我不需要的字段。他们为什么要帮忙?

这是因为 ApolloClient 和 Relay 一样,使用全局存储在客户端缓存你的数据。

为了为您执行此操作,需要全局 ID。出于某种原因,全局 ID 不是人们考虑的东西,事实上,当切换到 Relay 时,人们一直抱怨它。

ApolloClient 对此有一个巧妙的解决方案! (如果我错了,Apollo 团队会纠正我)他们允许您定义您的记录如何输入商店!默认情况下,它使用 typename 和 id 来创建 Relay 建议您创建的那种全局 ID。这就是为什么他们需要类型名称。

由于您在查询中关闭了类型名,Apollo 将做一些聪明的事情来尝试找出类型(以及存储中的键)。这些聪明的东西可能会给你带来麻烦。

如果您想创建自己的全局 ID 而不是使用所有这些聪明的东西,您可以这样指定:

const cache = new InMemoryCache({
  dataIdFromObject: object => object.key || null
});

https://www.apollographql.com/docs/react/advanced/caching.html#normalization