diff --git a/packages/x-data-grid-pro/src/hooks/features/dataSource/useGridDataSource.ts b/packages/x-data-grid-pro/src/hooks/features/dataSource/useGridDataSource.ts index b948c0a48745c..e8267b88adafe 100644 --- a/packages/x-data-grid-pro/src/hooks/features/dataSource/useGridDataSource.ts +++ b/packages/x-data-grid-pro/src/hooks/features/dataSource/useGridDataSource.ts @@ -8,7 +8,11 @@ import { useGridSelector, GridRowId, } from '@mui/x-data-grid'; -import { gridRowGroupsToFetchSelector, GridStateInitializer } from '@mui/x-data-grid/internals'; +import { + GridGetRowsParams, + gridRowGroupsToFetchSelector, + GridStateInitializer, +} from '@mui/x-data-grid/internals'; import { GridPrivateApiPro } from '../../../models/gridApiPro'; import { DataGridProProcessedProps } from '../../../models/dataGridProProps'; import { gridGetRowsParamsSelector, gridDataSourceErrorsSelector } from './gridDataSourceSelector'; @@ -60,6 +64,9 @@ export const useGridDataSource = ( ).current; const groupsToAutoFetch = useGridSelector(apiRef, gridRowGroupsToFetchSelector); const scheduledGroups = React.useRef(0); + const rowFetchSlice = React.useRef( + props.unstable_dataSource?.lazyLoaded ? { start: 0, end: 10 } : {}, // TODO: predict the initial `end` from the viewport + ); const onError = props.unstable_onDataSourceError; const [cache, setCache] = React.useState(() => @@ -85,13 +92,16 @@ export const useGridDataSource = ( apiRef.current.resetDataSourceState(); } - const fetchParams = gridGetRowsParamsSelector(apiRef); - + const fetchParams = { ...gridGetRowsParamsSelector(apiRef), ...rowFetchSlice.current }; const cachedData = apiRef.current.unstable_dataSource.cache.get(fetchParams); if (cachedData !== undefined) { const rows = cachedData.rows; - apiRef.current.setRows(rows); + if (props.unstable_dataSource?.lazyLoaded === true) { + apiRef.current.unstable_replaceRows(fetchParams.start, rows); + } else { + apiRef.current.setRows(rows); + } if (cachedData.rowCount) { apiRef.current.setRowCount(cachedData.rowCount); } @@ -109,7 +119,11 @@ export const useGridDataSource = ( if (getRowsResponse.rowCount) { apiRef.current.setRowCount(getRowsResponse.rowCount); } - apiRef.current.setRows(getRowsResponse.rows); + if (props.unstable_dataSource?.lazyLoaded === true) { + apiRef.current.unstable_replaceRows(fetchParams.start, getRowsResponse.rows); + } else { + apiRef.current.setRows(getRowsResponse.rows); + } apiRef.current.setLoading(false); } catch (error) { apiRef.current.setRows([]); @@ -117,7 +131,24 @@ export const useGridDataSource = ( onError?.(error as Error, fetchParams); } }, - [nestedDataManager, apiRef, props.unstable_dataSource?.getRows, onError], + [ + nestedDataManager, + apiRef, + props.unstable_dataSource?.getRows, + props.unstable_dataSource?.lazyLoaded, + onError, + rowFetchSlice, + ], + ); + + const fetchRowBatch = React.useCallback( + (fetchParams: GridGetRowsParams) => { + if (props.unstable_dataSource?.lazyLoaded && fetchParams.start && fetchParams.end) { + rowFetchSlice.current = { start: Number(fetchParams.start), end: fetchParams.end }; + } + return fetchRows(); + }, + [props.unstable_dataSource?.lazyLoaded, fetchRows], ); const fetchRowChildren = React.useCallback( @@ -267,6 +298,7 @@ export const useGridDataSource = ( 'paginationModelChange', runIfServerMode(props.paginationMode, fetchRows), ); + useGridApiEventHandler(apiRef, 'getRows', fetchRowBatch); const isFirstRender = React.useRef(true); React.useEffect(() => { diff --git a/packages/x-data-grid/src/hooks/features/rows/useGridRows.ts b/packages/x-data-grid/src/hooks/features/rows/useGridRows.ts index 2737b07ce94ce..b55cdf4ff63fb 100644 --- a/packages/x-data-grid/src/hooks/features/rows/useGridRows.ts +++ b/packages/x-data-grid/src/hooks/features/rows/useGridRows.ts @@ -462,6 +462,8 @@ export const useGridRows = ( ...state, rows: { ...state.rows, + loading: props.loading, + totalRowCount: Math.max(props.rowCount || 0, rootGroupChildren.length), dataRowIdToModelLookup, dataRowIdToIdLookup, dataRowIds, @@ -470,7 +472,7 @@ export const useGridRows = ( })); apiRef.current.publishEvent('rowsSet'); }, - [apiRef, props.signature, props.getRowId], + [apiRef, props.signature, props.getRowId, props.loading, props.rowCount], ); const rowApi: GridRowApi = {