React-Admin - 警告:遇到两个具有相同密钥的孩子

时间:2018-05-28 13:17:09

标签: admin-on-rest react-admin

当我更新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中,更改前和更改后的记录看起来相同(两者都需要id s,唯一的区别是当然的更改):

在UPDATE之前记录列表记录: Logging list records before UPDATE 这就是我在httpClient中返回更新数据的方法:

更新后记录列表记录: Logging list records after UPDATE

  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是必需的(根据最新版本的文档)。

我想在更新的那一刻,它出于某种原因(?)呈现两段记录。怎么解决?

2 个答案:

答案 0 :(得分:0)

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

如果您可以在codeSandBox example app上复制,请重新开启此问题。

答案 1 :(得分:0)

编辑:我想出了问题的出处:基本上在GET_LIST中,我返回的是ID号为number的记录。但是,在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重新作为字符串添加。