【问题标题】:React-Admin - Warning: Encountered two children with the same keyReact-Admin - 警告:遇到两个具有相同密钥的孩子
【发布时间】:2018-05-28 13:17:08
【问题描述】:

当我更新 resource 时,它会返回到 List View 并正确更新资源,但一会儿 List View 会闪烁并且控制台会报告警告:

Warning: Encountered two children with the same key, `2`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
in tbody (created by TableBody)
in TableBody (created by WithStyles(TableBody))
in WithStyles(TableBody) (created by DatagridBody)
in DatagridBody (created by shouldUpdate(DatagridBody))
in shouldUpdate(DatagridBody) (created by Datagrid)
in table (created by Table)
in Table (created by WithStyles(Table))
in WithStyles(Table) (created by Datagrid)
in Datagrid (created by WithStyles(Datagrid))
in WithStyles(Datagrid) (at UserList.js:13)
in div (created by ListView)
in div (created by Paper)
in Paper (created by WithStyles(Paper))
in WithStyles(Paper) (created by Card)
in Card (created by WithStyles(Card))
in WithStyles(Card) (created by ListView)
in div (created by ListView)
in ListView (created by ListController)
in ListController (created by TranslatedComponent(undefined))
in TranslatedComponent(undefined) (created by Connect(TranslatedComponent(undefined)))
in Connect(TranslatedComponent(undefined)) (created by List)
in List (created by WithStyles(List))
in WithStyles(List) (at UserList.js:12)
in UserList (created by WithPermissions)
in WithPermissions (created by Connect(WithPermissions))
in Connect(WithPermissions) (created by getContext(Connect(WithPermissions)))
in getContext(Connect(WithPermissions)) (created by Route)
in Route (created by Resource)
in Switch (created by Resource)
in Resource (created by Connect(Resource))
in Connect(Resource) (at App.js:26)
in Route (created by RoutesWithLayout)
in Switch (created by RoutesWithLayout)
in RoutesWithLayout (created by Route)
in div (created by Layout)
in main (created by Layout)
in div (created by Layout)
in div (created by Layout)
in Layout (created by WithStyles(Layout))
in WithStyles(Layout) (created by Connect(WithStyles(Layout)))
in Connect(WithStyles(Layout)) (created by LayoutWithTheme)
in MuiThemeProvider (created by LayoutWithTheme)
in LayoutWithTheme (created by Route)
in Route (created by CoreAdminRouter)
in Switch (created by CoreAdminRouter)
in div (created by CoreAdminRouter)
in CoreAdminRouter (created by Connect(CoreAdminRouter))
in Connect(CoreAdminRouter) (created by getContext(Connect(CoreAdminRouter)))
in getContext(Connect(CoreAdminRouter)) (created by Route)
in Route (created by CoreAdmin)
in Switch (created by CoreAdmin)
in Router (created by ConnectedRouter)
in ConnectedRouter (created by CoreAdmin)
in TranslationProvider (created by withContext(TranslationProvider))
in withContext(TranslationProvider) (created by Connect(withContext(TranslationProvider)))
in Connect(withContext(TranslationProvider)) (created by CoreAdmin)
in Provider (created by CoreAdmin)
in CoreAdmin (created by withContext(CoreAdmin))
in withContext(CoreAdmin) (at App.js:20)
in App (at index.js:6)

即使出现此警告,也会应用更新。在console中,更改前和更改后的记录看起来是一样的(都需要ids,唯一的区别是当然更改):

更新前的日志列表记录: 这就是我在 httpClient 中返回更新数据的方式:

更新后的日志列表记录:

  switch (type) {
    // (...)
    case UPDATE:
      return { data: { id, ...updateDiff } }; 
    // e.g.: id = 2 and updateDiff = {diffProp: 'newValue'}
  }

另一方面,当我在没有id 的情况下退货时:

  switch (type) {
    // (...)
    case UPDATE:
      return { data: updateDiff }; 
    // e.g.: id = 2 and updateDiff = {diffProp: 'newValue'}
  }

警告状态:Warning: Each child in an array or iterator should have a unique "key" prop.,所以我猜id 是必需的(根据最新版本的文档)。

我猜在更新的那一刻,它会出于某种原因(?)呈现一段时间的两条记录。如何解决?

【问题讨论】:

  • React-Admin 资源中需要有一个 ID 属性。如果您的 API 没有这样存储它们,那么数据提供者(Rest 客户端)需要从 API 响应中创建密钥。

标签: admin-on-rest react-admin


【解决方案1】:

编辑:我找到了我的问题的来源:基本上在GET_LIST 中,我返回了编号类型为 id 的记录。但是,在GET_ONE(而不是UPDATE)中,我返回了一条id 为string 类型的记录。很简单。

我也遇到了同样的问题。我使用的是我自己的数据提供者,我确信我在 UPDATE 之后返回了正确的格式,例如{ data: { id: <int>, ... } }.

由于某种原因,react-admin 似乎将我返回的 id 转换为字符串。当我打印传递给 Datagrid 的道具时,我看到 ids 数组包含类似 [308, '308', ...] 的内容(注意 308 id 出现两次,一次是整数,然后是字符串)。也许在某个地方存在类型强制错误,我需要对此进行调查。然而,我设法通过快速破解克服了这个问题,我像这样包装了 Datagrid

const MyDatagridHack = props => {
  const newIds = props.ids.filter(id => typeof(id) !== 'string');
  const newProps = Object.assign({}, props, { ids: newIds });
  return (
    <Datagrid {...newProps} rowClick="edit">
    </Datagrid>
  )
};

这只会从ids 数组中删除字符串。然后在哪里列出项目:

const ResourceList = props => {
  return (
    <List {...props}>
      <MyDatagridHack>
        <TextField source="id" />
        ...
      </MyDatagridHack>
    </List>
  );
};

这将删除警告,但我对它不是 100% 满意。我需要调查为什么将 id 再次添加为字符串。

【讨论】:

  • 解决了我的问题。答案在上面的编辑中
【解决方案2】:

我也遇到了这个警告。完全一样的情况。出于某种原因,ra 尝试将更新的记录附加为新记录,但操作类型恰好是“更新”。 我已经创建了这个问题,但开发人员无法重现它。 演示也可以正常工作。 问题链接:https://github.com/marmelab/react-admin/issues/1880

如果您可以在他们的codeSandBox example app 上复制它,请重新打开问题。

【讨论】:

    猜你喜欢
    • 2017-06-01
    • 2017-05-23
    • 1970-01-01
    • 2019-07-17
    • 2018-10-06
    • 2021-02-22
    • 2021-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多