【问题标题】:ES6 Relay list not mapping correctlyES6 中继列表未正确映射
【发布时间】:2016-04-20 05:48:09
【问题描述】:

我的地图函数渲染不正确。

内容上的项目是一个数组(见下文)。并且“内容”由其父级传递,其中包含从地图到 switch 语句的片段(此处未显示,因为我认为这不是问题,但可以在需要时粘贴)。问题图中列表项的显示顺序是产品、关于、联系我们、产品。因此,Home 被首先跳过并替换为最后一项“产品”。如果需要更多信息,请告诉我,谢谢。

const PageListItem = (props) => <Link to={props.item.id}>{props.item.value}</Link>;

const PageList = (props) => {
  return (
    <div style={styles.list}>
      { props.content.items.map( item => <PageListItem key={item._id} item={item} /> ) }
    </div>
  );
};

export default Relay.createContainer(Radium(PageList), {
  fragments: {
    content: () => Relay.QL`
      fragment on Content {
        items {
          _id
          id
          value
        }
      }
    `,
  }
});

被映射的数据的内容数组(来自猫鼬)

{ 
"_id" : ObjectId("920005cd1a38532d14349240"), 
"items" : [
    {
        "_id" : ObjectId("57102a0ad9601e34489223c1"), 
        "value" : "Home", 
        "id" : "110005cd1a38532d14349240", 
    }, 
    {
        "_id" : ObjectId("57102a0ad9601e34489223c0"), 
        "value" : "About", 
        "id" : "120005cd1a38532d14349240", 
    }, 
    {
        "_id" : ObjectId("57102a0ad9601e34489223bf"), 
        "value" : "Contact Us", 
        "id" : "130005cd1a38532d14349240", 
    }, 
    {
        "_id" : ObjectId("57102a0ad9601e34489223be"), 
        "value" : "Products", 
        "id" : "110005cd1a38532d14349240", 
    }
], 

【问题讨论】:

    标签: reactjs ecmascript-6 relay


    【解决方案1】:

    问题与中继对象识别有关。更多信息请访问specification

    如果您在服务器端使用graphql-relay-js,则公开对象(GraphQLObject 类型)应具有关联的id 属性,该属性被视为本地ID。 graphql-relay-js 具有帮助函数 globalIdField 来将此本地 ID 转换为全局 ID。客户端的 Relay 使用此全局 ID 来区分不同的数据。

    正如@tomáš-holub 已经指出的那样,Home 和 Products 的本地 ID 是相同的。由于 Products 在列表中排在后面,因此 Home 被覆盖。

    为了安全起见,我通常会在对象/数据中添加id 属性,这些属性最终会作为 GraphQL 对象公开。使用MongoDB时,这些本地的ids通常是_ids(xyz.id = abc._id.toHexString())。

    【讨论】:

      【解决方案2】:

      问题是您的“主页”和“产品”项的 id 相同。如果您更改一个 id,它应该可以正常工作。

      【讨论】:

      • 天哪,我以为我先尝试过它仍然无法正常工作。为什么这很重要,因为_id 不同并用于密钥。您认为这与 Link 的 to={props.item.id} 与另一个相同吗?我仍然希望它能够映射相同的值(_id 将是唯一的)
      • 我尝试在此处克隆功能:link 它似乎按预期工作,即链接(在本例中为 MyLink)具有预期的 id(即两个 id 相同)并且值为正确的。如果没有帮助,请尝试使用 alert(JSON.stringify(props))... 输出函数的参数...
      • 首先感谢您付出如此多的努力来提供帮助。所以我一直试图让它工作一段时间,但仍然无法正常工作。它不断渲染产品两次。即使_id不同,它仍然抱怨密钥相同。当我为 PageList 打印 JSON 时,它会拉出 Products、About、Contact Us、Products。 PageListItem 正在渲染它给出的内容。所以页面列表应该是问题所在,但是当我查看 GraphiQL 中的查询时,它返回了正确的列表。所以问题可能是中继中的 PageList 查询或其地图
      • 现在让我大吃一惊的是,如果我完全从渲染/查询中删除 id 字段并且只使用 '_id' 和 'value',它仍然说我有相同的键。然后,如果我进入数据库并将产品“id”更改为不同的产品,就像你第一次说的那样它工作正常......(但仍然没有在任何子组件中使用 id)
      • 所以我想出了一个解决方案。我认为 graphql 将“id”字段与 graphql id 混淆了。我将“id”字段中的字符串放入名为“key”的字符串中,一切正常,同时将“id”留空/空。奇怪的是,如果我使用 'id' 而它是空的,graphql 不会在列表中混淆它。遇到这种情况的其他人请注意:不要命名字段 id,因为 graphql 可能会混淆它。您认为我应该为此创建一个新答案吗?
      猜你喜欢
      • 2020-08-02
      • 1970-01-01
      • 2016-10-05
      • 1970-01-01
      • 1970-01-01
      • 2015-12-22
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多