Skip to content

[DataGridPro] Keep incremental root fetches from aborting in-flight children requests - #23327

Draft
JCQuintas wants to merge 3 commits into
mui:masterfrom
JCQuintas:fix/nested-lazy-loading-incremental-root-fetch
Draft

[DataGridPro] Keep incremental root fetches from aborting in-flight children requests#23327
JCQuintas wants to merge 3 commits into
mui:masterfrom
JCQuintas:fix/nested-lazy-loading-incremental-root-fetch

Conversation

@JCQuintas

Copy link
Copy Markdown
Member

Fixes #22715. Alternative approach to #23060.

The bug

With dataSource + treeData/row grouping + lazyLoading, the nested lazy loader routes its incremental root loads (viewport scrolling, dataSourceRevalidateMs polling) through the public dataSource.fetchRows(). That method clears the data source state, which aborts the child requests still in flight; their responses are then dropped by the RequestStatus.UNKNOWN guard in fetchRowChildren. Nothing re-requests them afterwards, so the affected groups stay as skeleton rows indefinitely.

Most visible with defaultGroupingExpansionDepth={-1} and with dataSourceRevalidateMs, where every poll tick cancelled the nested loads it had just started.

The fix

The collision is that one method serves two different intents: "the user asked for a refresh" and "the loader needs the next viewport chunk". They are split instead of changing what fetchRows() means:

  • fetchRootRowsIncremental() (private) fetches the root rows without invalidating. The nested lazy loader uses it for viewport loads and revalidation polls, the only two root fetches of that strategy that are not invalidating events.
  • fetchRows() keeps clearing the state for every strategy, so its public semantics are unchanged.
  • The clear now also marks the nested rows stale, so the root response that follows rebuilds the tree and re-issues the child requests it aborted. Previously an invalidating root fetch under this strategy aborted the children and left them as skeletons, so apiRef.current.dataSource.fetchRows() was not a working hard refresh for nested lazy loading.

Sort and filter already marked the rows stale by hand; they now share the same markRowsStale helper.

Notes

No public API change, so no docs or demo updates are needed. dataSource.fetchRows() keeps meaning "refresh from scratch" for every strategy, and it now actually rebuilds the tree under nested lazy loading.

fetchRows({ keepChildrenExpanded: false }) is still ignored by the nested lazy loading strategy (it is only read by handleGroupedDataUpdate). That is a pre-existing gap, left for a follow-up.

Each source change is covered by a test that was verified to fail without it:

  • incremental root loads do not abort or re-issue the in-flight child requests (Pro and Premium, fails if the incremental split is reverted)
  • the children aborted by an explicit fetchRows() are re-fetched (fails if the clear no longer marks the rows stale)
  • children responses computed for the previous sort, filter and row grouping model are dropped

…hildren requests

Nested lazy loading routed its incremental viewport loads and revalidation polls
through the public `dataSource.fetchRows()`, which clears the data source state and
therefore aborted the child requests still in flight. Their responses were dropped and
nothing re-requested them, leaving the groups as skeleton rows.

Split the two intents instead of changing what `fetchRows()` means:

- `fetchRootRowsIncremental()` fetches the root rows without invalidating, and the
  nested lazy loader uses it for viewport loads and revalidation.
- `fetchRows()` keeps invalidating for every strategy, and the clear now marks the
  nested rows stale so the following root response rebuilds the tree and re-issues the
  child requests it aborted.

Fixes mui#22715
@JCQuintas JCQuintas self-assigned this Aug 12, 2026
@JCQuintas JCQuintas added type: bug It doesn't behave as expected. scope: data grid Changes related to the data grid. plan: Pro Impact at least one Pro user. plan: Premium Impact at least one Premium user. feature: Server integration Better integration with backends, e.g. data source labels Aug 12, 2026
@code-infra-dashboard

code-infra-dashboard Bot commented Aug 12, 2026

Copy link
Copy Markdown

Deploy preview

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

Bundle size

Bundle Parsed size Gzip size
@mui/x-data-grid 🔺+111B(+0.03%) 🔺+37B(+0.03%)
@mui/x-data-grid-pro 🔺+409B(+0.08%) 🔺+137B(+0.09%)
@mui/x-data-grid-premium 🔺+427B(+0.06%) 🔺+132B(+0.06%)
@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.

@github-actions github-actions Bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Aug 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

…etch

Conflicts in `useGridDataSourceNestedLazyLoader.ts` against mui#23303, which added the
incomplete-filter-item guard to the same handler this branch refactored:

- kept both `fetchRootRowsIncremental` and `useGridDataSourceFilterModelChange`
- `handleGridFilterModelChange` runs the `hasFilterModelChanged` guard first, then
  `markRowsStale()`, which is the helper this branch extracted from the three lines
  master still inlines
@github-actions github-actions Bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged. label Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature: Server integration Better integration with backends, e.g. data source plan: Premium Impact at least one Premium user. plan: Pro Impact at least one Pro user. 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] Lazy loaded group grid with defaultGroupingExpansionDepth={-1} leaves some groups as skeletons.

1 participant