fix(table): Fix reset columns filter err (#38982)

* fix(table): fix filter state when reset columns

* fix(table): Fix the problem that the old filter state still takes effect when the list filter column changes

* test: add test case
This commit is contained in:
Amumu 2022-11-25 15:13:05 +08:00 committed by GitHub
parent e04c2d69ae
commit e77b59ad37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 192 additions and 2 deletions

View File

@ -11,7 +11,7 @@ import Select from '../../select';
import Tooltip from '../../tooltip';
import type { SelectProps } from '../../select';
import type { ColumnGroupType, ColumnType, TableProps } from '..';
import type { ColumnFilterItem, FilterDropdownProps, FilterValue } from '../interface';
import type { ColumnFilterItem, FilterDropdownProps, FilterValue, ColumnsType } from '../interface';
import { resetWarned } from '../../_util/warning';
import type { TreeColumnFilterItem } from '../hooks/useFilter/FilterDropdown';
@ -1826,6 +1826,189 @@ describe('Table.filter', () => {
);
});
it('Columns with filters should filter correctly after reset it.', () => {
interface DataType {
key: React.Key;
name?: string;
name1?: string;
age?: number;
address?: string;
}
const columns: ColumnsType<DataType> = [
{
title: 'Name',
dataIndex: 'name',
filters: [
{
text: 'Joe',
value: 'Joe',
},
{
text: 'Jim',
value: 'Jim',
},
{
text: 'Submenu',
value: 'Submenu',
children: [
{
text: 'Green',
value: 'Green',
},
{
text: 'Black',
value: 'Black',
},
],
},
],
// specify the condition of filtering result
// here is that finding the name started with `value`
onFilter: (value: string, record) => record.name?.indexOf(value) === 0,
sorter: (a, b) => a.name!.length - b.name!.length,
sortDirections: ['descend'],
},
{
title: 'Age',
dataIndex: 'age',
defaultSortOrder: 'descend',
sorter: (a, b) => a.age! - b.age!,
},
{
title: 'Address',
dataIndex: 'address',
filters: [
{
text: 'London',
value: 'London',
},
{
text: 'New York',
value: 'New York',
},
],
onFilter: (value: string, record) => record.address?.indexOf(value) === 0,
},
];
const App: React.FC = () => {
const [ddd, setData] = React.useState<Array<DataType>>([
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: '4',
name: 'Jim Red',
age: 32,
address: 'London No. 2 Lake Park',
},
]);
const [cs, setCs] = React.useState(columns);
const handleClick = () => {
setCs([
{
title: 'name1',
dataIndex: 'name1',
},
{
title: 'Address',
dataIndex: 'address',
filters: [
{
text: 'London',
value: 'London',
},
{
text: 'New York',
value: 'New York',
},
],
onFilter: (value: string, record) => record.address?.indexOf(value) === 0,
},
]);
setData([
{
key: '1',
name1: 'Joe Brown',
address: 'New York No. 1 Lake Park',
},
{
key: '2',
name1: 'Jim Green',
address: 'London No. 1 Lake Park',
},
{
key: '3',
name1: 'Joe Black',
address: 'Sidney No. 1 Lake Park',
},
{
key: '4',
name1: 'Jim Red',
address: 'London No. 2 Lake Park',
},
]);
};
return (
<div>
<span className="rest-btn" onClick={handleClick}>
refresh
</span>
<Table columns={cs} dataSource={ddd} />
</div>
);
};
const { container } = render(<App />);
expect(container.querySelectorAll('.ant-table-tbody .ant-table-row').length).toEqual(4);
// Open
fireEvent.click(container.querySelector('.ant-table-filter-trigger')!);
function getFilterMenu() {
return container.querySelector('.ant-table-filter-dropdown');
}
// Seems raf not trigger when in useEffect for async update
// Need trigger multiple times
function refreshTimer() {
for (let i = 0; i < 3; i += 1) {
act(() => {
jest.runAllTimers();
});
}
}
const items = getFilterMenu()?.querySelectorAll('li.ant-dropdown-menu-item');
fireEvent.click(items?.[0]!);
fireEvent.click(
getFilterMenu()?.querySelector('.ant-table-filter-dropdown-btns .ant-btn-primary')!,
);
refreshTimer();
expect(container.querySelectorAll('.ant-table-tbody .ant-table-row').length).toEqual(1);
fireEvent.click(container.querySelector('.rest-btn')!);
expect(container.querySelectorAll('.ant-table-tbody .ant-table-row').length).toEqual(4);
});
describe('filter tree mode', () => {
it('supports filter tree', () => {
jest.spyOn(console, 'error').mockImplementation(() => undefined);

View File

@ -211,6 +211,9 @@ function useFilter<RecordType>({
const mergedFilterStates = React.useMemo(() => {
const collectedStates = collectFilterStates(mergedColumns, false);
if (collectedStates.length === 0) {
return collectedStates;
}
let filteredKeysIsAllNotControlled = true;
let filteredKeysIsAllControlled = true;
collectedStates.forEach(({ filteredKeys }) => {
@ -223,7 +226,11 @@ function useFilter<RecordType>({
// Return if not controlled
if (filteredKeysIsAllNotControlled) {
return filterStates;
// Filter column may have been removed
const keyList = (mergedColumns || []).map((column, index) =>
getColumnKey(column, getColumnPos(index)),
);
return filterStates.filter(({ key }) => keyList.includes(key));
}
warning(