我们的GraphQL服务器使用包含一组对象的数据来响应查询,每个对象共享相同的id
和不同的值的不同值。例如,我们可能有一个类似于:
[
{ id: 123, name: 'foo', type: 'bar', cost: 5 },
{ id: 123, name: 'foo', type: 'bar', cost: 6 },
{ id: 123, name: 'foo', type: 'bar', cost: 7 },
{ id: 123, name: 'foo', type: 'bar', cost: 8 }
]
我们可以在“网络”选项卡中看到来自服务器的响应中包含正确的数据。但是,当它通过Apollo Client模块进行处理时,数组已经转换为可能如下所示:
[
{ id: 123, name: 'foo', type: 'bar', cost: 5 },
{ id: 123, name: 'foo', type: 'bar', cost: 5 },
{ id: 123, name: 'foo', type: 'bar', cost: 5 },
{ id: 123, name: 'foo', type: 'bar', cost: 5 }
]
基本上我们看到的是,如果数组中的所有对象共享id
的相同值,则数组中的所有对象都将成为数组中第一个对象的副本。
这是Apollo Client的预期行为吗?我们认为它可能与不正确的缓存有关,但我们也想知道Apollo客户端是否认为具有相同id
的后续数组成员是同一个对象。
答案 0 :(得分:1)
看起来这是预期的行为。 Apollo客户端在id
上进行标准化。
答案 1 :(得分:0)
正如另一个答案所暗示的那样,这是因为 Apollo 通过 ID 进行了标准化。有一个非常广泛的 article on the official blog 解释了它的基本原理以及底层机制。
简而言之,从 Apollo 的缓存中可以看出,您的对象数组包含同一个对象的 4 个实例(id 123
)。同一个ID,同一个对象。
这对 Apollo 来说是一个公平的假设,但在您的情况下则不然。 你必须明确告诉 Apollo,这些确实是 4 种不同的项目,应该区别对待。
过去我们使用 dataIdFromObject
,您可以看到 example here。
今天,您将使用 typePolicies
和 keyfields
:
const cache = new InMemoryCache({
typePolicies: {
YourItem: {
// Combine the fields that make your item unique
keyFields: ['id', 'cost'],
}
},
});