Hello,
I recently inherited an old project which was using v5 Kendo libraries. I have upgraded all of these to the latest as of today but in doing so I now am noticing a 'flash' of data before the correct data is rendered. I'm unable to produce a isolated demo but I will try my best to outline the components as minimally as possible.
Before I dive into the code what I have found is that a tableAction of 'getInnerTable' is being called to create and populate the "correct" data and the flash of incorrect data is actually the data supplied to the rowData prop on the Grid component.
Here's the code:
interfaceTableProps<T> {
title?: string;
tableModal?: { onClick: () =>void; text: string };
rowData: T[] | null;
gridDefaultState: State;
isLoading: boolean;
tableActions: {
removeItem?: (data: any) =>void;
updateItem?: (data: any) =>void;
getInnerTable: (
columnField: string,
rowData: T[],
isLastColumn: boolean,
tableActions: {
removeItem?: (data: T) => void;
updateItem?: (data: T) => void;
}
) =>ReactNode;
};
children?: ReactNode;
hasBorder?: boolean;
}
constTable = <T extends {}>({
isLoading,
title,
tableModal,
rowData,
gridDefaultState,
tableActions,
children,
hasBorder = true,
}: TableProps<T>) => {
const [columnFields, setColumnFields] = useState<string[] | null>(null);
const [gridDataState, setGridDataState] = useState<State>(gridDefaultState);
console.log('rowData', rowData);
useEffect(() => {
if (rowData && rowData.length > 0) {
setColumnFields([...Object.keys(rowData[0]), 'Icons']);
}
}, [rowData]);
consthandleGridDataStateChange = (e: GridDataStateChangeEvent) => {
setGridDataState({ ...e.dataState });
};
console.log('columnFields:', columnFields);
constGridTable = () => {
return (
<Grid
data={rowData && process(rowData, gridDataState)}
sortable={true}
{...gridDataState}
onDataStateChange={handleGridDataStateChange}
selectable={{
enabled: true,
mode: 'single',
}}
>
{children}
{rowData &&
columnFields?.map((columnField: string, index) => {
console.log('columnField:', columnField);
const isLastColumn: boolean = columnFields.length - 1 === index;
return tableActions.getInnerTable(columnField, rowData, isLastColumn, tableActions);
})}
</Grid>
);
};
return (
<StyledWrapper noData={!isLoading && !rowData?.length} hasBorder={hasBorder}>
{title && <TitleWithButton title={title} buttonData={tableModal} hasBottomPadding />}
{isLoading ? (
<SpinnerWrapper>
<Spinner />
</SpinnerWrapper>
) : (
<GridTable />
)}
</StyledWrapper>
);
};
exportdefaultTable;
The getInnerTable function:
export const getOrganisationInnerTable = <T,>(
columnField: string,
rowData: Array<T & OrganisationColumn>,
isLastColumn: boolean,
tableActions: {
removeItem?: (data: T) => void;
updateItem?: (data: T) => void;
}
) => {
if (columnField === OrganisationStyledColumns.organisationName) {
return (
<GridColumn
key={columnField}
field="title.name"
title={'Organisation name'}
cell={(props: GridCellProps) => <OrganisationNameColumn {...props} />}
columnMenu={(props) => ColumnFilterSearchMenu(rowData, props)}
/>
);
}
if (columnField === OrganisationStyledColumns.createdDate) {
return (
<GridColumn
key={columnField}
field={columnField}
title={'Added'}
filter="date"
format="{0:dd-MM-yyyy}"
columnMenu={(props) => {
return DateColumnFilter(rowData, props);
}}
/>
);
}
return getInnerTableColumn(columnField, rowData, isLastColumn, tableActions);
};