【问题标题】:Apollo Client replaces an array of objects with the same id and different values with an array of copies of the first objectApollo 客户端将具有相同 id 和不同值的对象数组替换为第一个对象的副本数组
【发布时间】:2018-04-06 22:12:01
【问题描述】:

我们的 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 客户端模块的处理时,该数组已被转换为如下所示的东西:

[
  { 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 的后续数组成员是同一个对象。

【问题讨论】:

    标签: javascript graphql apollo-client


    【解决方案1】:

    看起来这是预期的行为。 Apollo 客户端在 id 上正常化。

    【讨论】:

    【解决方案2】:

    正如另一个答案所暗示的那样,这是因为 Apollo 通过 ID 标准化。有一个非常广泛的 article on the official blog 解释了它的基本原理以及基本机制。

    简而言之,从 Apollo 的缓存中可以看出,您的对象数组包含相同对象的 4 个实例(id 123)。相同的 ID,相同的对象。

    这是 Apollo 方面的一个公平假设,但在您的情况下并非如此。 你必须明确告诉 Apollo,这确实是 4 种不同的物品,应该区别对待。

    过去我们使用dataIdFromObject,您可以看到example here

    今天,您将使用typePolicieskeyfields

    const cache = new InMemoryCache({
      typePolicies: {
        YourItem: {
          // Combine the fields that make your item unique
          keyFields: ['id', 'cost'],
        }
      },
    });
    

    Docs

    【讨论】:

      【解决方案3】:

      它对我有用: const cache: InMemoryCache = new InMemoryCache({ dataIdFromObject: o => false )};

      上一个答案也解决了这个问题! 您也可以在后端更改密钥名称(例如 id => itemId),不会有任何问题!

      【讨论】:

      猜你喜欢
      • 2021-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      • 1970-01-01
      相关资源
      最近更新 更多