diff --git a/packages/grid/x-data-grid/src/hooks/features/filter/useGridFilter.tsx b/packages/grid/x-data-grid/src/hooks/features/filter/useGridFilter.tsx index a3e7595503585..644c0f86331cb 100644 --- a/packages/grid/x-data-grid/src/hooks/features/filter/useGridFilter.tsx +++ b/packages/grid/x-data-grid/src/hooks/features/filter/useGridFilter.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils'; import { GridEventListener } from '../../../models/events'; import { DataGridProcessedProps } from '../../../models/props/DataGridProps'; import { GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity'; @@ -485,7 +486,7 @@ export const useGridFilter = ( /** * EFFECTS */ - React.useEffect(() => { + useEnhancedEffect(() => { if (props.filterModel !== undefined) { apiRef.current.setFilterModel(props.filterModel); } diff --git a/packages/grid/x-data-grid/src/hooks/features/sorting/useGridSorting.ts b/packages/grid/x-data-grid/src/hooks/features/sorting/useGridSorting.ts index c5fb01768eab4..a5847ddb7527e 100644 --- a/packages/grid/x-data-grid/src/hooks/features/sorting/useGridSorting.ts +++ b/packages/grid/x-data-grid/src/hooks/features/sorting/useGridSorting.ts @@ -1,4 +1,5 @@ import * as React from 'react'; +import { unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils'; import { GridEventListener } from '../../../models/events'; import { DataGridProcessedProps } from '../../../models/props/DataGridProps'; import { GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity'; @@ -366,7 +367,7 @@ export const useGridSorting = ( /** * EFFECTS */ - React.useEffect(() => { + useEnhancedEffect(() => { if (props.sortModel !== undefined) { apiRef.current.setSortModel(props.sortModel); } diff --git a/packages/grid/x-data-grid/src/tests/filtering.DataGrid.test.tsx b/packages/grid/x-data-grid/src/tests/filtering.DataGrid.test.tsx index eabad01e11f18..74c38b517c6c9 100644 --- a/packages/grid/x-data-grid/src/tests/filtering.DataGrid.test.tsx +++ b/packages/grid/x-data-grid/src/tests/filtering.DataGrid.test.tsx @@ -11,6 +11,7 @@ import { GridToolbar, } from '@mui/x-data-grid'; import { getColumnValues } from 'test/utils/helperFn'; +import { spy } from 'sinon'; const isJSDOM = /jsdom/.test(window.navigator.userAgent); @@ -1248,4 +1249,76 @@ describe(' - Filter', () => { ); }).not.to.throw(); }); + + it('should update the filter model on columns change', () => { + const columns = [{ field: 'id' }, { field: 'brand' }]; + const rows = [ + { id: 0, brand: 'Nike' }, + { id: 1, brand: 'Adidas' }, + { id: 2, brand: 'Puma' }, + ]; + const onFilterModelChange = spy(); + + function Demo(props: Omit) { + return ( +
+ +
+ ); + } + const { setProps } = render(); + expect(getColumnValues(1)).to.deep.equal(['Puma']); + + setProps({ columns: [{ field: 'id' }] }); + expect(getColumnValues(0)).to.deep.equal(['0', '1', '2']); + expect(onFilterModelChange.callCount).to.equal(1); + expect(onFilterModelChange.lastCall.firstArg).to.deep.equal({ items: [] }); + }); + + // See https://github.com/mui/mui-x/issues/9204 + it('should not clear the filter model when both columns and filterModel change', async () => { + const columns = [{ field: 'id' }, { field: 'brand' }]; + const rows = [ + { id: 0, brand: 'Nike' }, + { id: 1, brand: 'Adidas' }, + { id: 2, brand: 'Puma' }, + ]; + + const onFilterModelChange = spy(); + + function Demo(props: Omit) { + return ( +
+ +
+ ); + } + const { setProps } = render(); + expect(getColumnValues(1)).to.deep.equal(['Puma']); + + setProps({ + columns: [{ field: 'id' }], + filterModel: { + items: [{ field: 'id', operator: 'equals', value: '1' }], + }, + }); + expect(getColumnValues(0)).to.deep.equal(['1']); + expect(onFilterModelChange.callCount).to.equal(0); + }); }); diff --git a/packages/grid/x-data-grid/src/tests/sorting.DataGrid.test.tsx b/packages/grid/x-data-grid/src/tests/sorting.DataGrid.test.tsx index c10f6568c574f..aca6e0b84d832 100644 --- a/packages/grid/x-data-grid/src/tests/sorting.DataGrid.test.tsx +++ b/packages/grid/x-data-grid/src/tests/sorting.DataGrid.test.tsx @@ -1,8 +1,9 @@ import * as React from 'react'; -import { createRenderer, fireEvent, screen, act } from '@mui/monorepo/test/utils'; +import { createRenderer, fireEvent, screen, act, waitFor } from '@mui/monorepo/test/utils'; import { expect } from 'chai'; import { DataGrid, DataGridProps, GridSortModel, useGridApiRef, GridApi } from '@mui/x-data-grid'; import { getColumnValues, getColumnHeaderCell } from 'test/utils/helperFn'; +import { spy } from 'sinon'; const isJSDOM = /jsdom/.test(window.navigator.userAgent); @@ -538,4 +539,71 @@ describe(' - Sorting', () => { act(() => apiRef.current.updateRows([{ id: 0, brand: 'Patagonia' }])); expect(getColumnValues(0)).to.deep.equal(['Fila', 'Patagonia', 'Puma']); }); + + it('should update the sorting model on columns change', async () => { + const columns = [{ field: 'id' }, { field: 'brand' }]; + const rows = [ + { id: 0, brand: 'Nike' }, + { id: 1, brand: 'Adidas' }, + { id: 2, brand: 'Puma' }, + ]; + const onSortModelChange = spy(); + + function Demo(props: Omit) { + return ( +
+ +
+ ); + } + const { setProps } = render(); + expect(getColumnValues(1)).to.deep.equal(['Adidas', 'Nike', 'Puma']); + + setProps({ columns: [{ field: 'id' }] }); + await waitFor(() => { + expect(getColumnValues(0)).to.deep.equal(['0', '1', '2']); + expect(onSortModelChange.callCount).to.equal(1); + expect(onSortModelChange.lastCall.firstArg).to.deep.equal([]); + }); + }); + + // See https://github.com/mui/mui-x/issues/9204 + it('should not clear the sorting model when both columns and sortModel change', async () => { + const columns = [{ field: 'id' }, { field: 'brand' }]; + const rows = [ + { id: 0, brand: 'Nike' }, + { id: 1, brand: 'Adidas' }, + { id: 2, brand: 'Puma' }, + ]; + + const onSortModelChange = spy(); + + function Demo(props: Omit) { + return ( +
+ +
+ ); + } + const { setProps } = render(); + expect(getColumnValues(1)).to.deep.equal(['Adidas', 'Nike', 'Puma']); + + setProps({ columns: [{ field: 'id' }], sortModel: [{ field: 'id', sort: 'desc' }] }); + await waitFor(() => { + expect(getColumnValues(0)).to.deep.equal(['2', '1', '0']); + expect(onSortModelChange.callCount).to.equal(0); + }); + }); });