2

When I update a resource, it returns to List View and correctly updates the resource, but for a moment the List View blinks and console reports a warning:

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)

The update is applied, even though this warning occurs. In the console, the records before change and after change seem identical (both have required ids, the only difference is the change of course):

Logging list records before UPDATE: Logging list records before UPDATE This is how i return data on update in my httpClient:

Logging list records after UPDATE: Logging list records after UPDATE

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

On the other hand, when I return it without id:

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

the warning states: Warning: Each child in an array or iterator should have a unique "key" prop., so I guess the id is required (according to the latest version of docs).

I guess in the moment of update it renders for some time both records for some reason (?). How to solve it?

Sebastian
  • 1,225
  • 1
  • 16
  • 27
  • React-Admin resources need to have an ID property in them. If your API does not store them like that then the data provider (Rest client) needs to create the key from the API response. – kunal pareek May 30 '18 at 07:03

2 Answers2

1

Edit: I figured out the source my issue: basically in GET_LIST I was returning records with ids of type number. However, in GET_ONE (and not UPDATE) I was returning a record with id of type string. Pretty straightforward.

I came across the same issue as well. I was using my own data provider and I'm sure I return the right format after UPDATE, e.g. { data: { id: <int>, ... } }.

For some reason it seems react-admin takes the id I return and converts it to string. When I print the props passed down to Datagrid I see the ids array containing something like [308, '308', ...] (notice 308 id shows up twice, once as integer and then as string). Maybe there's a type coercion bug somewhere down the line, I need to investigate this. However, I managed to overcome this with a quick hack, I wrapped Datagrid like this

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>
  )
};

This will just remove the strings from ids array. Then where you list the items:

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

This will remove the warnings but I'm not 100% happy with it. I need to investigate why the id is added again as string.

dryhten
  • 26
  • 3
0

I met this warning too. Completely same case. For some reason ra tries to append updated record as new one, but the action type was exactly 'UPDATE'. I've created the issue, but developer coudnt reproduce it. Demo works fine too. Issue link: https://github.com/marmelab/react-admin/issues/1880

If you can reproduce it on their codeSandBox example app, please reopen the issue.

ashkart
  • 3
  • 3