Skip to content

[DataGrid] Fix row tree reset when a data source grid becomes visible - #23288

Open
JCQuintas wants to merge 2 commits into
mui:masterfrom
JCQuintas:bg/fix-23262
Open

[DataGrid] Fix row tree reset when a data source grid becomes visible#23288
JCQuintas wants to merge 2 commits into
mui:masterfrom
JCQuintas:bg/fix-23262

Conversation

@JCQuintas

Copy link
Copy Markdown
Member

Summary

Fixes #23262.

A data source grid with treeData + lazyLoading inside a React <Activity> boundary lost its lazy-loaded children and skeleton rows, and had childrenExpanded reset on every group node, whenever the boundary went hiddenvisible.

<Activity> re-runs effects when it becomes visible again, even though no dependency changed. The props-sync effect at the bottom of useGridRows was not resilient to that, because its only guard against re-applying rows is an identity comparison:

const currentRows = props.dataSource ? gridDataRowsSelector(apiRef) : props.rows;
const areNewRowsAlreadyInState =
  apiRef.current.caches.rows.rowsBeforePartialUpdates === currentRows;

rowsBeforePartialUpdates holds the raw array passed to the last setRows(), while gridDataRowsSelector builds a new array on every recompute. Under a data source those are never the same reference, so areNewRowsAlreadyInState is effectively always false and the effect falls through to a full throttledRowsChange rebuild. That normally goes unnoticed, because the effect only runs when a dependency actually changed — but <Activity> re-fires it with identical dependencies, and the rebuild drops the skeleton rows (they are not data rows) and resets the expansion state.

With a data source the rows live in the state rather than in props, so there is never a new set of rows to apply here. The fix makes that explicit instead of asking a question that cannot be answered by reference identity. Only a new getRowId still requires a rebuild, to re-key the rows already in the state — tracked with a ref, the same way the effect already tracks rowCount a few lines above.

This is a second, distinct site from #22603. That PR stopped the <Activity> re-show from re-fetching in useGridDataSourceBase; with it merged, the row tree was still destroyed by this effect. Verified in both directions on top of master at 77536d2:

without this fix with this fix
children 50 → 50 50 → 50
childrenExpanded true → false true → true
skeleton rows 50 → 0 50 → 50

Tests

  • dataSourceTreeData.DataGridPro.test.tsx — the loaded children, the skeleton rows and the expansion state survive an <Activity> hide/show. Fails on master.
  • dataSourceTreeData.DataGridPro.test.tsx — a real rowCount prop update is still applied, covering the fall-through path that the early return must not swallow.
  • dataSource.DataGridPro.test.tsx — a getRowId change still re-keys the rows of a data source grid. This path had no coverage, and an earlier version of this fix silently broke it while the whole suite stayed green.

Changelog

Fixed the Data Grid dropping lazy-loaded rows, skeleton rows and the group expansion state when a data source grid re-appears inside a React <Activity> boundary.

The props-sync effect in `useGridRows` guards against re-applying rows with an
identity comparison against `caches.rows.rowsBeforePartialUpdates`. With a data
source the rows live in the state rather than in props, and
`gridDataRowsSelector` builds a new array on every recompute, so that comparison
never holds and the effect rebuilds the whole row tree every time it re-runs.

React `<Activity>` re-runs effects with unchanged dependencies when it becomes
visible again. The rebuild then dropped the lazy-loaded children and the
skeleton rows, and reset `childrenExpanded` on every group node.

Rows never come from props under a data source, so there is never a new set to
apply. Only a new `getRowId` requires a rebuild, to re-key the rows already in
the state.

Closes mui#23262
@JCQuintas JCQuintas added type: bug It doesn't behave as expected. scope: data grid Changes related to the data grid. labels Aug 4, 2026
@JCQuintas JCQuintas self-assigned this Aug 4, 2026
@code-infra-dashboard

code-infra-dashboard Bot commented Aug 4, 2026

Copy link
Copy Markdown

Deploy preview

https://deploy-preview-23288--material-ui-x.netlify.app/
QR code for https://deploy-preview-23288--material-ui-x.netlify.app/

Bundle size

Bundle Parsed size Gzip size
@mui/x-data-grid 🔺+103B(+0.03%) 🔺+41B(+0.03%)
@mui/x-data-grid-pro 🔺+100B(+0.02%) 🔺+41B(+0.03%)
@mui/x-data-grid-premium 🔺+103B(+0.01%) 🔺+43B(+0.02%)
@mui/x-charts 0B(0.00%) 0B(0.00%)
@mui/x-charts-pro 0B(0.00%) 0B(0.00%)
@mui/x-charts-premium 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) 0B(0.00%)
@mui/x-scheduler 0B(0.00%) 0B(0.00%)
@mui/x-scheduler-premium 0B(0.00%) 0B(0.00%)
@mui/x-chat 0B(0.00%) 0B(0.00%)
@mui/x-license 0B(0.00%) 0B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@JCQuintas
JCQuintas marked this pull request as ready for review August 4, 2026 12:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: data grid Changes related to the data grid. type: bug It doesn't behave as expected.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[data grid] Data source tree data: loaded children, skeleton rows, and expansion state are lost when the grid re-appears inside React <Activity>

1 participant