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

[datagrid] How to autosize columns on rows fetch #10578

Closed
Tracked by #9328
cherniavskii opened this issue Oct 4, 2023 · 6 comments · Fixed by #10822
Closed
Tracked by #9328

[datagrid] How to autosize columns on rows fetch #10578

cherniavskii opened this issue Oct 4, 2023 · 6 comments · Fixed by #10822
Labels
component: data grid This is the name of the generic UI component, not the React module! docs Improvements or additions to the documentation feature: Column resize recipe

Comments

@cherniavskii
Copy link
Member

cherniavskii commented Oct 4, 2023

The problem in depth 🔍

The autosizeOnMount prop that works great when the rows data is available on grid mount.
But it's not obvious how to autosize columns when the rows are fetched asynchronously after the grid is mounted.

We need to document a recommended solution for this use case.

Here is what I tried:

1. Call apiRef.current.autosizeColumns when rows are fetched

https://codesandbox.io/s/lucid-roentgen-ynchfy?file=/Demo.tsx

Pros:

Cons:

  • Does not work - the grid has not rendered the rows yet, so calling autosizeColumns can only measure column headers.

2. Same as 1, but wrap apiRef.current.autosizeColumns with setTimeout

https://codesandbox.io/s/sad-pasteur-cdyscq?file=/Demo.tsx

Pros:

  • It works

Cons:

  • Column width jump

3. Use ReactDOM.flushSync + apiRef.current.updateRows (instead of rows prop) and apiRef.current.autosizeColumns

https://codesandbox.io/s/interesting-ben-vh9ndk?file=/Demo.tsx

Pros:

  • It works
  • No column width jump

Cons:

  • Not an obvious solution

4. Render the data grid after the data is fetched and use the autosizeOnMount prop.

Pros:

  • It works

Cons:

  • Cannot show the data grid in the loading state while fetching the data
  • Won't work on data refetch as the grid stays mounted. Changing the key will reset the grid state.

Your environment 🌎

`npx @mui/envinfo`
  Don't forget to mention which browser you used.
  Output from `npx @mui/envinfo` goes here.

Search keywords: datagrid autosize columns

@cherniavskii cherniavskii added docs Improvements or additions to the documentation component: data grid This is the name of the generic UI component, not the React module! status: waiting for maintainer These issues haven't been looked at yet by a maintainer feature: Column resize labels Oct 4, 2023
@romgrk
Copy link
Contributor

romgrk commented Oct 9, 2023

I think I'd favor adding a recipe for 3.

@cherniavskii cherniavskii added recipe and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Oct 17, 2023
@michelengelen
Copy link
Member

I think I'd favor adding a recipe for 3.

Thought the same while reading ... it provides the most value, since there will be a "blank" state instead of no grid being rendered at all

@Madsim
Copy link

Madsim commented Nov 20, 2023

In my opinion this should be handled by the library. When reading the docs it says that "Autosizing" is the default behaviour in pro- and premium-plans, so I would expect it to try to autosize on "rows" change and maybe give me an option to control this myself.

@efie45
Copy link

efie45 commented Feb 8, 2024

Like @Madsim said, this seems like counter-intuitive behavior to me as well. Especially since there is a loading prop. It makes it difficult to use the default DataGrid loading functionality.

For example, if you're doing something like this:

const { data, isLoading } = useQuery(myQueryOptions);

then you need to pass in an empty array to rows while isLoading is true. Once the data finally fetches, the autosizing is still based on the size of your empty data set.

To me it would make sense to have a prop autoSizeOnLoad or autoSizeOnInitialLoad or even just have autoSizeOnMount default to resizing only after loading is set to false.

@michelengelen michelengelen removed their assignment Jun 3, 2024
@crestianiam
Copy link

I noticed that Solution 3 suggests using ReactDOM.flushSync, but the official React documentation states that using flushSync is uncommon and can hurt the performance of your app. For this reason, I opted for Solution 2, which seems to work fine. Here's the code I used:

useEffect(() => {
    let outerTimeoutId: NodeJS.Timeout | null = null;
    let innerTimeoutId: NodeJS.Timeout | null = null;

    outerTimeoutId = setTimeout(() => {
        innerTimeoutId = setTimeout(() => {
            if (apiRef?.current) {
                apiRef.current.autosizeColumns(autoSizeOptions);
            }
        }, 200);
    }, 1000);

    return () => {
        if (outerTimeoutId) clearTimeout(outerTimeoutId);
        if (innerTimeoutId) clearTimeout(innerTimeoutId);
    };
}, [rows, apiRef, autoSizeOptions]);

This version better handles cases where the component gets unmounted, avoiding potential problems or errors caused by running timeouts after the component has been unmounted.

The timeout solution seems to work, but I've noticed that the outliersFactor factor doesn't seem to function correctly when rows.length is greater than pageSize. When I set pageSize to be greater than or equal to rows.length, the autosize seems to fix itself.
Has anyone encountered a similar issue? I haven't been able to fully debug it yet. In the meantime, I've set includeOutliers directly to true because, even with a factor of 4 which should be quite broad it didn't seem to adjust properly.

@ATSeeq
Copy link

ATSeeq commented Jan 30, 2025

I was struggling with the same issue for the past couple of days.
Having tried all the above solutions, there was always something amiss.
I ended up using the autosizeOnMount. Then to 'force' the grid to remount once the data is fetched, I provide the data grid with a new key.

Are there any potential issues with this solution, that I might be overlooking?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: data grid This is the name of the generic UI component, not the React module! docs Improvements or additions to the documentation feature: Column resize recipe
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants