我在React Native中使用react-apollo的Query-Component从后端获取数据。

结果看起来像这样:

[
  {
    id: 1,
    name: 'US Election',
    parties: [
      {
        name: 'democrats',
        id: 4,
        pivot: {
          id: 3,
          answers: [
            {
              id: 13,
              question_id: 3,
              reason: 'Lorem ipsum',
              __typename: "Answer"
            },
            {
              id: 14,
              question_id: 5,
              reason: 'Lorem ipsum',
              __typename: "Answer"
            },
          ],
          __typename: "ElectionPartyPivot"
        },
        __typename: "Party"
      },
    ],
    __typename: "Election"
  },
  {
    id: 2,
    name: 'Another one',
    parties: [
      {
        name: 'democrats',
        id: 4,
        pivot: {
          id: 7,
          answers: [
            {
              id: 15,
              question_id: 7,
              reason: 'Lorem ipsum',
              __typename: "Answer"
            },
            {
              id: 18,
              question_id: 9,
              reason: 'Lorem ipsum',
              __typename: "Answer"
            },
          ],
          __typename: "ElectionPartyPivot"
        },
        __typename: "Party"
      },
    ],
    __typename: "Election"
  }
]


现在,当我console.log结果时,第二个选举“另一个”从第一个条目pivot具有US Election

我认为这是因为阿波罗内部正在进行标准化(因为双方的ID都相同),但是我不确定如何解决它,因此它无法对此进行标准化或正确对其进行标准化。

编辑

我想出了这个解决方案,但是看起来很棘手。现在,我与聚会一起获得了lection_id,并在缓存中创建了另一个标识符。我想知道这是否是好习惯吗?

const cache = new InMemoryCache({
  dataIdFromObject: object => {
    switch (object.__typename) {
      case 'Party': return `${object.election_id}:${object.id}`;
      default: return defaultDataIdFromObject(object);
    }
  }
});

const client = new ApolloClient({
  uri: config.apiUrl,
  cache
});

最佳答案

是的,在这种情况下,必须提供自定义dataIdFromObject。如果将来还有其他Party:${object.election_id}:${object.id}字段需要同样的处理,则应考虑使用Election作为密钥。

从根本上讲,这是架构设计方式的问题。 GraphQL中有一个基本假设,即虽然GraphQL中的节点可能相互之间具有关系,但它们也彼此完全独立。也就是说,在同一上下文中,基于响应中是否存在其他节点,同一节点不应代表不同的数据。

不幸的是,这就是这种响应的结构方式-我们有一个代表Party的节点,但是其字段因与另一个节点-Election的关系而异。

有两种方法可以解决此类问题。一种方法是使用每个Party的不同ID维护每个Election的不同实例。 Party类型背后的基本数据模型不会代表一个政党一生,而是仅在一次选举中代表一个政党。

另一种方法是重组架构,以更准确地表示节点之间的关系。例如,一个支持这种查询的模式:

{
  elections {
    id
    name
    parties {
      id
      name
      # omit pivot field on Party type
    }
    # instead because pivots are related directly to elections, add this field
    pivots {
      id
      answers
      # because we may still care what party the pivot is associated with as well
      # we can add a party field to pivot to show that relationship
      party {
        id
        name
      }
    }
  }
}

关于javascript - Apollo奇怪地更改了查询结果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55256262/

10-13 02:13