[GH-DEV #1859]Handsontable losing meta information on re-render

Tags: #<Tag:0x00007efc61738d68>

This might be similar to On re-render, cell meta data lost.
I am using React with typescript. I have a functional component wrapper HotTableComponent that wraps the HotTable component. The intent is to use this wrapper in different pages with minimum configuration:

export const HotTableComponent = forwardRef<HotTableClass, HotTableComponentProps>(function HotTableComponent(
props,
forwardedRef
) {

return (
<HotTable
ref={hotRef}
colWidths={props.colWidths}

The validation logic is all encompassed within HotTableComponent and the idea is that it will validate the data, and call some setters for:

  1. the data
  2. cells that have errors
  3. boolean if any cell is faulty (so that I disable some high level Upload button accordingly)

A higher level component is rendering HotTableComponent and passing those setters. Those setters are basically useState setters. When the user copy/pastes data, HotTableComponent validates it, and calls setData, setDataValidity, setErrors, etc. and the higher level component will display those errors and enable/disable Upload button

The problem is changing state on the higher level component is re-rendering HotTableComponent, which is re-rendering HotTable, and that’s causing the cell meta objects to be lost and the red highlighting of the cells to disappear

I tried calling re-rendering in different places (hotRef.current?.hotInstance?.render()), validating upon load on HotTableComponent, etc. and nothing worked. I even tried to manually save the cell meta in afterValidate function, and then restoring the cell meta upon load and even that didn’t fix the highlighting issue

afterValidate =(…) =>
{
props.setCellMeta?.(hotRef.current?.hotInstance?.getCellsMeta());
}

and during load:
export const HotTableComponent = forwardRef<HotTableClass, HotTableComponentProps>(function HotTableComponent(
props,
forwardedRef
) {
const hotRef = useRef<HotTableClass | null>(null);
useImperativeHandle(forwardedRef, () => hotRef.current as HotTableClass);

const inst = hotRef.current?.hotInstance;

props.cellMeta?.forEach((cell) => {
    hotRef.current?.hotInstance?.setCellMetaObject(cell.row, cell.col, cell);
});
hotRef.current?.hotInstance?.render();

I have the code here https://stackblitz.com/edit/vitejs-vite-vkutwe?file=src%2FApp.tsx but I think I’m using different versions so I can’t get this to compile and run properly…

Please advise
Thanks
Raffi

Hi @rsakabedoyan

Thank you for contacting us. I checked your example and it compiles and run, but I’m not sure about the steps to reproduce the issue. Can you please provide those?

Try inputting something in Email column that’s not in email format. You’ll see the red background appear and disappear immediately. Same for dropdown. What’s happening is that validations are running, HotTableComponent is calling some functions that set states in App component, causing App to rerender HotTableComponent which causes the CellMetas validity to be lost

Hi @rsakabedoyan

Thank you for the details. I can already see that it’s quite customized solution so I will need a little bit more time to check it properly. I will update you as soon as I have more information about the possible source of this issue.

Hi @rsakabedoyan

After further investigation it seems that the issue is caused by the way our React wrapper currently works. Combining it with the additional layer of your higher component that causes the re-rendering.

We are currently working on a new version of the wrapper to make it more stable and working better natively with React so I will update you once it’s done so we can check if that will solve the problem.

Is there a timeline for fixing this issue? when will the wrapper be released?

Hi @rsakabedoyan

The new React wrapper should be released in about a month. I will let you know once it’s out.

A quick update: We already merged the PR to develop https://github.com/handsontable/handsontable/pull/11212 and will start a code review soon.