React-Admin - 警告:遇到两个 children 使用相同的密钥

React-Admin - Warning: Encountered two children with the same key

当我更新 resource 时,它 returns 到 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,唯一的区别当然是更改):

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

更新后记录列表记录:

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

另一方面,当我 return 它没有 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 是必需的(根据最新版本的文档)。

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

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

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

编辑:我找到了问题的根源:基本上在 GET_LIST 中,我 returning 了带有类型编号 ID 的记录。但是,在 GET_ONE(而不是 UPDATE)中,我正在 returning 一条 id 类型为字符串的记录。很直接。

我也遇到了同样的问题。我使用的是自己的数据提供程序,我确定我 return 更新后的格式正确,例如{ data: { id: <int>, ... } }.

出于某种原因,react-admin 似乎采用了 id I return 并将其转换为字符串。当我打印传递给 Datagrid 的 props 时,我看到 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 再次添加为字符串。