Unplanned
Last Updated: 27 Jul 2023 07:55 by ADMIN
Stoyan
Created on: 09 Nov 2022 22:18
Category: KendoReact
Type: Bug Report
1
Grid Grouping and Footer rows have the same React key when dataItemKey prop is provided

https://stackblitz.com/edit/react-haejnu?file=app%2Fmain.tsx%3AL115

It is a common use case to provide Grid's dataItemKey property to make sure changes are properly reflected per documentation - https://www.telerik.com/kendo-react-ui/components/grid/api/GridProps/#toc-dataitemkey

However, when this accessor property is provided (usually a unique ID on all groups and items), Kendo uses it instead of its default auto-incremented `'ai' + absoluteIndex` key to index the <GridRow /> for each group's header and footer - giving them the same value and causing React to throw multiple warning about duplicate keys. This makes it unreliable to specify dataItemKey property when using the grouping feature with aggregate footers as it messes up with React's reconciliation mechanism.

6 comments
ADMIN
Konstantin Dikov
Posted on: 26 Nov 2022 08:45

Hello Stoyan,

Thank you for the detailed information about your scenario.

After reviewing the use case I do agree that it might be a common scenario where the data structure is handled in a different way and that having unique id values for the group items (or in this case the parent items) should not throw an error.

With the above in mind, I am re-opening the item.

 

Regards,
Konstantin Dikov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Stoyan
Posted on: 23 Nov 2022 17:08

Hi Konstantin,

Indeed our data is not aggregated on the client as we have thousands of records that we need to aggregate on several levels, so we do it on the server and return a GroupResult, as stated in point 3 of the docs.

We don't make use of setGroupIds to identify the group rows for the purpose of controlling collapsedIds, because we can set the unique IDs of those groups on the server while processing the whole data.

Given that GroupResult interface doesn't impose any restrictions on what the grouping ID should be called and Kendo doesn't rely on that (it's for our own use in onExpandChange handlers) we just used the same "Id" property to identify our group rows (instead of "groupId"), the same way we identify our data items. Which brings us to this issue.

We just updated our server code to use a different ID property for the group rows and it solved the problem. So to rephrase - everything works fine if we follow the examples and the built-in data utils from Kendo, but if we build our data on the server, there is a restriction that is not documented - we can't use the same "ID" property to identify the groups as the one used for the data items. Even if we rely on the Kendo data tools' "setGroupIds" to populate these unique IDs on the client after the data is returned from the server, there would be an undocumented limitation that our dataItemKey for the data items cannot be called "groupId".

Given that DataGrid grouping functionality is usually used in enterprise applications with unique custom requirements, I think it is possible that other people might hit the same issue. I believe a proper fix for that occasion would be no more than a line of code from your side and is better than bloating the documentation with an obscure restriction.

ADMIN
Konstantin Dikov
Posted on: 23 Nov 2022 15:23

Hi Stoyan,

Thank you for the additional information.

I have tried the scenario where I have added the same field to the group items manually and I was able to observe the issue:

However, if the parent items in your scenario have dataItemKey as the child items, this sounds like a tree structure and not a grouping generated by the groupBy method (or the process method). If that is the case, it might be more suitable to use the TreeList component instead:

If I am misunderstanding the scenario, could you please elaborate the use case of the group items having an ID field which is intended for the data items?

Regards,
Konstantin Dikov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Stoyan
Posted on: 16 Nov 2022 16:40
Also, the reason it doesn't throw warnings in Konstantin's example is because the groups don't have the ProductID property, so Kendo falls back to using the absolute index for the keys of these rows as if dataItemKey was not provided. In our application groups and items all have ID field, which we use for dataItemKey and the issue is still there.
Stoyan
Posted on: 16 Nov 2022 16:32

Hello Konstantin.

I am sorry I did not clarify this earlier.

I am aware that groupId is not available on the leaf nodes, just the parent group items. However, this has no relation to the issue, as even if you supply a property that is available on both groups and items (as we do in our real application, I just don't want to modify the data in the example so much) - the result is the same. The problem comes from the following lines of code in Kendo's Grid.tsx source:

const dataItemKey = this.props.dataItemKey && getter(this.props.dataItemKey)(item.dataItem);
const absoluteIndex = rowIndex + (this.vs.propsSkip || 0);
const rowId = dataItemKey ? dataItemKey : 'ai' + absoluteIndex;
const detailRowId = rowId + '_1';
const gridRow = dataRow(item, rowId, dataIndex);
currentAriaRowIndex = absoluteIndex + rowIndexStart + detailRowCount;

body
.push((
  <GridRow
  key={rowId}

 

The dataItemKey constant in the above snippet respects only the id of the group row (we have 1 group record with unique ID in the data, but 2 rows generated for it - one group header row and one group footer row) - so we end up with them having the same key.

I am attaching a screenshot to show which two rows I am talking about - they both have their key set to the same value: "0UnitsInStock_Alice MuttonProductName". If we do not provide the dataItemKey prop then as seen from the snippet kendo uses the absoluteIndex of the row, which is different for group header and footer rows and there is no issue.

ADMIN
Konstantin Dikov
Posted on: 15 Nov 2022 14:11

Hello Stoyan,

Thank you for contacting us.

The issue in the example is due to the fact that you are setting the dataItemKey to the groupId field, which is added to the group items only. The dataItemKey should specify the unique values in the data items, which in this scenario is the ProductID field:

Hope this helps.

 

Regards,
Konstantin Dikov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.