diff --git a/packages/grid/data-grid/src/DataGrid.test.tsx b/packages/grid/data-grid/src/DataGrid.test.tsx
index 519e402fac8d3..eb7b774134136 100644
--- a/packages/grid/data-grid/src/DataGrid.test.tsx
+++ b/packages/grid/data-grid/src/DataGrid.test.tsx
@@ -60,6 +60,30 @@ describe('', () => {
container.firstChild.firstChild.firstChild,
);
});
+
+ it('should apply the page prop correctly', () => {
+ const rows = [
+ {
+ id: 0,
+ brand: 'Nike',
+ },
+ {
+ id: 1,
+ brand: 'Addidas',
+ },
+ {
+ id: 2,
+ brand: 'Puma',
+ },
+ ];
+ render(
+
+
+
,
+ );
+ const cell = document.querySelector('[role="cell"][aria-colindex="0"]')!;
+ expect(cell).to.have.text('Addidas');
+ });
});
});
diff --git a/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts b/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts
index 6cf0d4dcb1aa6..9f5f69c36c4ea 100644
--- a/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts
+++ b/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts
@@ -61,6 +61,7 @@ export const usePagination = (
),
};
const stateRef = React.useRef(initialState);
+ const prevPageRef = React.useRef(1);
const [state, dispatch] = React.useReducer(paginationReducer, initialState);
const updateState = React.useCallback(
@@ -74,16 +75,22 @@ export const usePagination = (
const setPage = React.useCallback(
(page: number) => {
- page = stateRef.current.pageCount >= page ? page : stateRef.current.pageCount;
- apiRef.current.renderPage(
- stateRef.current.paginationMode === FeatureModeConstant.client ? page : 1,
- );
-
+ let hasPageChanged = false;
+ if (stateRef.current.rowCount > 0) {
+ page = stateRef.current.pageCount >= page ? page : stateRef.current.pageCount;
+ apiRef.current.renderPage(
+ stateRef.current.paginationMode === FeatureModeConstant.client ? page : 1,
+ );
+ hasPageChanged = true;
+ }
const params: PageChangeParams = {
...stateRef.current,
page,
};
- apiRef.current.publishEvent(PAGE_CHANGED, params);
+ if (hasPageChanged && prevPageRef.current !== page) {
+ apiRef.current.publishEvent(PAGE_CHANGED, params);
+ prevPageRef.current = page;
+ }
if (stateRef.current.page !== page) {
updateState({ page });
}
@@ -147,6 +154,17 @@ export const usePagination = (
}
}, [setPageSize, logger, getAutoPageSize]);
+ useApiEventHandler(apiRef, PAGE_CHANGED, options.onPageChange);
+ useApiEventHandler(apiRef, PAGESIZE_CHANGED, options.onPageSizeChange);
+
+ const onResize = React.useCallback(() => {
+ if (options.autoPageSize) {
+ resetAutopageSize();
+ }
+ }, [options.autoPageSize, resetAutopageSize]);
+
+ useApiEventHandler(apiRef, RESIZE, onResize);
+
React.useEffect(() => {
stateRef.current = state;
}, [state]);
@@ -157,14 +175,6 @@ export const usePagination = (
}
}, [apiRef, stateRef, apiRef.current?.isInitialised]);
- React.useEffect(() => {
- updateState({ paginationMode: options.paginationMode! });
- }, [options.paginationMode, updateState]);
-
- React.useEffect(() => {
- setPage(options.page != null ? options.page : 1);
- }, [options.page, setPage]);
-
React.useEffect(() => {
const rowCount = options.rowCount == null ? rows.length : options.rowCount;
if (rowCount !== state.rowCount) {
@@ -172,9 +182,7 @@ export const usePagination = (
const newPageCount = getPageCount(state.pageSize, rowCount);
updateState({ pageCount: newPageCount, rowCount });
- if (state.page > newPageCount) {
- setPage(newPageCount);
- }
+ setPage(state.page);
}
}, [
rows.length,
@@ -187,6 +195,14 @@ export const usePagination = (
state.page,
]);
+ React.useEffect(() => {
+ updateState({ paginationMode: options.paginationMode! });
+ }, [options.paginationMode, updateState]);
+
+ React.useEffect(() => {
+ setPage(options.page != null ? options.page : 1);
+ }, [options.page, setPage]);
+
React.useEffect(() => {
if (
!options.autoPageSize &&
@@ -203,17 +219,6 @@ export const usePagination = (
}
}, [options.autoPageSize, resetAutopageSize, columns.visible.length]);
- useApiEventHandler(apiRef, PAGE_CHANGED, options.onPageChange);
- useApiEventHandler(apiRef, PAGESIZE_CHANGED, options.onPageSizeChange);
-
- const onResize = React.useCallback(() => {
- if (options.autoPageSize) {
- resetAutopageSize();
- }
- }, [options.autoPageSize, resetAutopageSize]);
-
- useApiEventHandler(apiRef, RESIZE, onResize);
-
const paginationApi: PaginationApi = {
setPageSize,
setPage,
diff --git a/packages/grid/x-grid/src/XGrid.test.tsx b/packages/grid/x-grid/src/XGrid.test.tsx
index 15b4b6a3f93dd..29fae4d49884f 100644
--- a/packages/grid/x-grid/src/XGrid.test.tsx
+++ b/packages/grid/x-grid/src/XGrid.test.tsx
@@ -1,7 +1,7 @@
import * as React from 'react';
import { screen, createClientRender, act, fireEvent } from 'test/utils';
import { expect } from 'chai';
-import { XGrid } from '@material-ui/x-grid';
+import { XGrid, useApiRef } from '@material-ui/x-grid';
import { useData } from 'packages/storybook/src/hooks/useData';
function getActiveCell() {
@@ -212,6 +212,42 @@ describe('', () => {
expect(row).to.not.have.class('Mui-selected');
expect(checkbox).to.have.property('checked', false);
});
+ it('should apply setPage correctly', () => {
+ const rows = [
+ {
+ id: 0,
+ brand: 'Nike',
+ },
+ {
+ id: 1,
+ brand: 'Addidas',
+ },
+ {
+ id: 2,
+ brand: 'Puma',
+ },
+ ];
+ const GridTest = () => {
+ const apiRef = useApiRef();
+ React.useEffect(() => {
+ apiRef.current.setPage(2);
+ });
+ return (
+
+
+
+ );
+ };
+ render();
+ const cell = document.querySelector('[role="cell"][aria-colindex="0"]')!;
+ expect(cell).to.have.text('Addidas');
+ });
});
describe('sorting', () => {
diff --git a/packages/storybook/src/stories/grid-pagination.stories.tsx b/packages/storybook/src/stories/grid-pagination.stories.tsx
index 76f0b9a136e52..bc949627fa72a 100644
--- a/packages/storybook/src/stories/grid-pagination.stories.tsx
+++ b/packages/storybook/src/stories/grid-pagination.stories.tsx
@@ -264,3 +264,55 @@ export function ServerPaginationWithEventHandler() {
);
}
+export function Page1Prop() {
+ const data = useData(2000, 200);
+
+ return (
+
+ action('pageChange')(p)}
+ />
+
+ );
+}
+export function Page2Prop() {
+ const data = useData(2000, 200);
+
+ return (
+
+ action('pageChange')(p)}
+ />
+
+ );
+}
+export function Page2Api() {
+ const data = useData(2000, 200);
+ const apiRef = useApiRef();
+
+ React.useEffect(() => {
+ apiRef.current.setPage(2);
+ }, [apiRef]);
+
+ return (
+
+ action('pageChange')(p)}
+ />
+
+ );
+}