Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[data grid] autosizeColumns on columnVisibilityModelChange fails #14922

Closed
ddecrulle opened this issue Oct 11, 2024 · 9 comments · Fixed by #14393
Closed

[data grid] autosizeColumns on columnVisibilityModelChange fails #14922

ddecrulle opened this issue Oct 11, 2024 · 9 comments · Fixed by #14393
Labels
bug 🐛 Something doesn't work component: data grid This is the name of the generic UI component, not the React module! feature: Column resize feature: Column visibility

Comments

@ddecrulle
Copy link

ddecrulle commented Oct 11, 2024

Steps to reproduce

https://stackblitz.com/edit/react-qsqwfi?file=Demo.tsx

Steps:

  1. Manage Columns
  2. Remove one column

Current behavior

I want to resize my grid when column visibility changes. So, I tried to run autosizeColumns when the columnVisibilityModelChange event is fired. However, when a column is removed, this results in the following error:

Error: Cannot read properties of undefined (reading 'computedWidth')

It appears that the autosizeColumns function attempts to access the computedWidth of a column that has already been removed.

Expected behavior

No error in console

Context

I tried the same behavior without controlling the value of columnVisibilityModel, and it worked as expected without any errors.

Your environment

npx @mui/envinfo
System:
    OS: macOS 15.0.1
  Binaries:
    Node: 22.6.0 - /opt/homebrew/bin/node
    npm: 10.8.2 - /opt/homebrew/bin/npm
    pnpm: 9.4.0 - /opt/homebrew/bin/pnpm
  Browsers:
    Chrome: 129.0.6668.100
    Edge: Not Found
    Safari: 18.0.1
  npmPackages:
    @emotion/react: ^11.11.3 => 11.11.3 
    @emotion/styled: ^11.11.0 => 11.11.0 
    @mui/base: ^5.0.0-beta.58 => 5.0.0-beta.58 
    @mui/core-downloads-tracker:  6.1.3 
    @mui/icons-material: 5.14.15 => 5.14.15 
    @mui/material: ^6.1.3 => 6.1.3 
    @mui/private-theming:  6.1.3 
    @mui/styled-engine:  6.1.3 
    @mui/system: ^6.1.3 => 6.1.3 
    @mui/types:  7.2.17 
    @mui/utils:  6.1.3 
    @mui/x-data-grid: ^7.19.0 => 7.19.0 
    @mui/x-internals:  7.18.0 
    @types/react: ^18.2.43 => 18.2.57 
    react: ^18.2.0 => 18.2.0 
    react-dom: ^18.2.0 => 18.2.0 
    styled-components:  6.1.8 
    typescript: ^5.4.5 => 5.4.5 

Search keywords: autosizeColumns, columnVisibilityModelChange

@ddecrulle ddecrulle added bug 🐛 Something doesn't work status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Oct 11, 2024
@github-actions github-actions bot added the component: data grid This is the name of the generic UI component, not the React module! label Oct 11, 2024
@michelengelen
Copy link
Member

@KenanYusuf could you have a look into this? This might just be a race condition or a false order of execution.

@michelengelen michelengelen changed the title [Datagrid] : autosizeColumns at event columnVisibilityModelChange with columnVisibilityModel is controlled fall [data grid] autosizeColumns on columnVisibilityModelChange fails Oct 11, 2024
@michelengelen
Copy link
Member

Sry, I just had a look and you can just call the autosizing on every render, or when the model changes in state:

React.useEffect(() => {
  apiRef.current.autosizeColumns({
    expand: true,
    includeHeaders: true,
    includeOutliers: false,
  });
}, [columnVisibilityModel]);

This will fix it!

@michelengelen michelengelen added status: waiting for author Issue with insufficient information and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Oct 11, 2024
@michelengelen
Copy link
Member

Sry again. It will still throw an error when you hide a column with the column management panel. Showing it through that or hiding from the column menu works though! 🤷🏼

@ddecrulle
Copy link
Author

ddecrulle commented Oct 11, 2024

I haven’t found a solution for this issue yet except in uncontrolled mode for columnVisibility. Once it’s resolved, do you have any recommendations for the best approach? Should I select the columnVisibilityModel from the state or subscribe to the event?

First approach :

const columnVisibilityModel = useGridSelector(
    apiRef,
    gridColumnVisibilityModelSelector
);

useEffect(() => {
    apiRef.current.autosizeColumns(autosizeOptions);
}, [columnVisibilityModel]);

Second Approach :

useGridApiEventHandler(apiRef, "columnVisibilityModelChange", () => {
    apiRef.current.autosizeColumns(autosizeOptions);
});

@github-actions github-actions bot added status: waiting for maintainer These issues haven't been looked at yet by a maintainer and removed status: waiting for author Issue with insufficient information labels Oct 11, 2024
@MBilalShafi
Copy link
Member

It seems to be a state out-of-sync between visibleColumns and the renderContext as the renderContext seem to take one extra render to update, you could delay the execution of autosizeColumns as a workaround.

https://stackblitz.com/edit/react-qsqwfi-hifr2v?file=Demo.tsx

A simple internal fix could be to skip rendering the outdated columns:

diff --git a/packages/x-data-grid/src/components/GridRow.tsx b/packages/x-data-grid/src/components/GridRow.tsx
index 03c8b20797..e0d360e2dc 100644
--- a/packages/x-data-grid/src/components/GridRow.tsx
+++ b/packages/x-data-grid/src/components/GridRow.tsx
@@ -443,6 +443,9 @@ const GridRow = React.forwardRef<HTMLDivElement, GridRowProps>(function GridRow(
     const column = visibleColumns[i];
     const indexInSection = i - pinnedColumns.left.length;
 
+    if (!column) {
+      continue;
+    }
     cells.push(getCell(column, indexInSection, i, middleColumnsLength));
   }
   if (hasVirtualFocusCellRight) {

For a more sophisticated fix, we might want to ensure visibleColumns and renderContext never go out-of-sync.

@romgrk I'd be curious to know what you think about the quick fix I suggested.

@MBilalShafi
Copy link
Member

Do you have any recommendations for the best approach? Should I select the columnVisibilityModel from the state or subscribe to the event?

First approach :

const columnVisibilityModel = useGridSelector(
    apiRef,
    gridColumnVisibilityModelSelector
);

useEffect(() => {
    apiRef.current.autosizeColumns(autosizeOptions);
}, [columnVisibilityModel]);

Second Approach :

useGridApiEventHandler(apiRef, "columnVisibilityModelChange", () => {
    apiRef.current.autosizeColumns(autosizeOptions);
});

If it's being used in a component that is rendered inside the Data Grid, it's better to go with the approach 1 as useGridSelector ensures proper reactivity. See https://mui.com/x/react-data-grid/state/#with-usegridselector for reference

For the use-cases outside the Data Grid (like the example attached with this issue), approach 2 should be the way to go.

@MBilalShafi MBilalShafi removed the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Oct 15, 2024
@romgrk
Copy link
Contributor

romgrk commented Oct 15, 2024

The quick fix LGTM. The state management needs work to be able to sync parts like visibilityColumn and renderContext, our state updates are async currently.

@KenanYusuf
Copy link
Contributor

I encountered this issue on #14393 when switching between list view and normal view. I have made @MBilalShafi's suggested fix there https://github.com/mui/mui-x/pull/14393/files#diff-f3fbb1e13f754215032d5ddeec1713b812667d502e65c180c3ca9eabf048c7cbR447-R449

Copy link

This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue.
Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.

Note

@ddecrulle How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something doesn't work component: data grid This is the name of the generic UI component, not the React module! feature: Column resize feature: Column visibility
Projects
Status: 🔖 Ready
Development

Successfully merging a pull request may close this issue.

5 participants