Skip to content

Commit

Permalink
Debounced rows fetch
Browse files Browse the repository at this point in the history
  • Loading branch information
arminmeh committed Jan 8, 2025
1 parent 86d6e2a commit 65cd604
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
useGridRegisterStrategyProcessor,
runIf,
} from '@mui/x-data-grid/internals';
import { unstable_debounce as debounce } from '@mui/utils';
import { GridPrivateApiPro } from '../../../models/gridApiPro';
import { DataGridProProcessedProps } from '../../../models/dataGridProProps';
import { gridGetRowsParamsSelector, gridDataSourceErrorsSelector } from './gridDataSourceSelector';
Expand Down Expand Up @@ -323,6 +324,8 @@ export const useGridDataSource = (
[apiRef],
);

const debouncedFetchRows = React.useMemo(() => debounce(fetchRows, 0), [fetchRows]);

const handleStrategyActivityChange = React.useCallback<
GridEventListener<'strategyAvailabilityChange'>
>(() => {
Expand Down Expand Up @@ -385,17 +388,17 @@ export const useGridDataSource = (
useGridApiEventHandler(
apiRef,
'sortModelChange',
runIf(defaultRowsUpdateStrategyActive, () => fetchRows()),
runIf(defaultRowsUpdateStrategyActive, () => debouncedFetchRows()),
);
useGridApiEventHandler(
apiRef,
'filterModelChange',
runIf(defaultRowsUpdateStrategyActive, () => fetchRows()),
runIf(defaultRowsUpdateStrategyActive, () => debouncedFetchRows()),
);
useGridApiEventHandler(
apiRef,
'paginationModelChange',
runIf(defaultRowsUpdateStrategyActive, () => fetchRows()),
runIf(defaultRowsUpdateStrategyActive, () => debouncedFetchRows()),
);

const isFirstRender = React.useRef(true);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from 'react';
import { throttle } from '@mui/x-internals/throttle';
import { unstable_debounce as debounce } from '@mui/utils';
import {
useGridApiEventHandler,
useGridSelector,
Expand Down Expand Up @@ -415,6 +416,15 @@ export const useGridDataSourceLazyLoader = (
[props.unstable_lazyLoadingRequestThrottleMs, handleRenderedRowsIntervalChange],
);

const debouncedFetchRows = React.useCallback(
(params: Partial<GridGetRowsParams>) =>
debounce(
() => privateApiRef.current.unstable_dataSource.fetchRows(GRID_ROOT_GROUP_ID, params),
0,
),
[privateApiRef],
);

const handleGridSortModelChange = React.useCallback<GridEventListener<'sortModelChange'>>(
(newSortModel) => {
rowsStale.current = true;
Expand All @@ -438,12 +448,9 @@ export const useGridDataSourceLazyLoader = (
};

privateApiRef.current.setLoading(true);
privateApiRef.current.unstable_dataSource.fetchRows(
GRID_ROOT_GROUP_ID,
adjustRowParams(getRowsParams),
);
debouncedFetchRows(adjustRowParams(getRowsParams));
},
[privateApiRef, filterModel, paginationModel.pageSize, adjustRowParams],
[privateApiRef, filterModel, paginationModel.pageSize, adjustRowParams, debouncedFetchRows],
);

const handleGridFilterModelChange = React.useCallback<GridEventListener<'filterModelChange'>>(
Expand All @@ -458,9 +465,9 @@ export const useGridDataSourceLazyLoader = (
};

privateApiRef.current.setLoading(true);
privateApiRef.current.unstable_dataSource.fetchRows(GRID_ROOT_GROUP_ID, getRowsParams);
debouncedFetchRows(getRowsParams);
},
[privateApiRef, sortModel, paginationModel.pageSize],
[privateApiRef, sortModel, paginationModel.pageSize, debouncedFetchRows],
);

const handleStrategyActivityChange = React.useCallback<
Expand Down
15 changes: 15 additions & 0 deletions packages/x-data-grid-pro/src/tests/dataSource.DataGridPro.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,21 @@ describeSkipIf(isJSDOM)('<DataGridPro /> - Data source', () => {
});
});

it('should re-fetch the data once if multiple models have changed', async () => {
const { setProps } = render(<TestDataSource />);
await waitFor(() => {
expect(fetchRowsSpy.callCount).to.equal(1);
});

setProps({ paginationModel: { page: 1, pageSize: 10 } });
setProps({ sortModel: [{ field: 'name', sort: 'asc' }] });
setProps({ filterModel: { items: [{ field: 'name', value: 'John', operator: 'contains' }] } });

await waitFor(() => {
expect(fetchRowsSpy.callCount).to.equal(2);
});
});

describe('Cache', () => {
it('should cache the data using the default cache', async () => {
render(<TestDataSource />);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,20 @@ describeSkipIf(isJSDOM)('<DataGridPro /> - Data source lazy loader', () => {
});
});

it('should re-fetch the data once if multiple models have changed', async () => {
const { setProps } = render(<TestDataSourceLazyLoader />);
await waitFor(() => {
expect(fetchRowsSpy.callCount).to.equal(1);
});

setProps({ sortModel: [{ field: 'name', sort: 'asc' }] });
setProps({ filterModel: { items: [{ field: 'name', value: 'John', operator: 'contains' }] } });

await waitFor(() => {
expect(fetchRowsSpy.callCount).to.equal(2);
});
});

describe('Viewport loading', () => {
it('should render skeleton rows if rowCount is bigger than the number of rows', async () => {
render(<TestDataSourceLazyLoader />);
Expand Down

0 comments on commit 65cd604

Please sign in to comment.