inovua / reactdatagrid

Empower Your Data with the best React Data Grid there is
https://reactdatagrid.io
Other
3.45k stars 57 forks source link

🐛 Bug: setColumnSizeAuto throws when column virtualization is enabled #395

Open lfpose opened 7 months ago

lfpose commented 7 months ago

what edition are you using - community / enterprise enterprise

version for @inovua/reactdatagrid-communityor @inovua/reactdatagrid-enterprise 5.10.2

What you did: Try to set column size auto with skipHeaders = false and virtualization enabled.

// target is the id of the column
gridRef?.current?.setColumnSizeAuto?.(target, false);

What happened: Error is thrown, because its trying to read a property from an undefined value.

Error in reactdatagrid code: useColumnsSizing.js

      headerCells.find(function (cell) {
        var cellProps = cell.props; // error here
        if (cellProps.id === column.id) {
          headerCell = cell.getDOMNode();
        }
      });

This throws an error when cell is undefined. cell is undefined if grid has many columns and is using virtualization

Reproduction https://codesandbox.io/s/wandering-sun-dzgx34?file=/src/App.js

instructions: scroll to the right then click autosize. Unexpected error is thrown.

Problem description:

Error is thrown and column is not resized as expected. It is expected that a column should be resized when calling the method. When we scroll, as soon as first column is out of the screen its virtualized. When calling setColumnSizeAuto with a virtualized column, then it will throw an error. Note: only if skipHeaders = false

Suggested solution:

Validate that the cell is not undefined or use optional chaining useColumnsSizing.js

headerCells.find(function (cell) {
        var cellProps = cell?.props;
        if (cellProps?.id === column.id) {
          headerCell = cell.getDOMNode();
        }
      });
tomjcb commented 7 months ago

It is happening to me as well. I'll add my observations :

It seems that it happens when virtualization is ON and when there are too much columns to be displayed on the screen.

When I log getHeader().getCells() , it appears that cells that aren't on the screen are considered empty.

Image (there a 32 key because this column is sticky to the end, so it is rendered on the screen) image

headerCells.find(function (cell) {
        var cellProps = cell.props;
        if (cellProps.id === column.id) {
          headerCell = cell.getDOMNode();
        }
});

So my guess is that the cell is sometimes undefined because it gets skipped from getCells(). That's why it triggers the error "Cannot read properties of undefined (reading 'props')".

It doesn't happen when skipHeader is true, because it doesn't enter this part (I think)