Fix sort order broken issue when columns were put in render

will handle these situation

- with 'key'
- with function has same stringify value

close #12870
close #12737
This commit is contained in:
afc163 2018-11-01 13:42:53 +08:00
parent a70d64451b
commit a7f17b4cde
2 changed files with 124 additions and 2 deletions

View File

@ -358,6 +358,17 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
};
}
isSameColumn(a: ColumnProps<T> | null, b: ColumnProps<T> | null) {
if (a && b && a.key && a.key === b.key) {
return true;
}
return a === b || shallowEqual(a, b, (value: any, other: any) => {
if (typeof value === 'function' && typeof other === 'function') {
return value === other || value.toString() === other.toString();
}
});
}
toggleSortOrder(column: ColumnProps<T>) {
if (!column.sorter) {
return;
@ -366,8 +377,7 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
// 只同时允许一列进行排序,否则会导致排序顺序的逻辑问题
let newSortOrder: 'descend' | 'ascend' | undefined;
// 切换另一列时,丢弃 sortOrder 的状态
const oldSortOrder = (sortColumn === column || shallowEqual(sortColumn, column))
? sortOrder : undefined;
const oldSortOrder = this.isSameColumn(sortColumn, column) ? sortOrder : undefined;
// 切换排序状态,按照降序/升序/不排序的顺序
if (!oldSortOrder) {
newSortOrder = 'descend';

View File

@ -1,3 +1,4 @@
/* eslint-disable react/no-multi-comp */
import React from 'react';
import { render, mount } from 'enzyme';
import Table from '..';
@ -263,4 +264,115 @@ describe('Table.sorter', () => {
expect(nameColumn.find('.ant-table-column-sorter-down').at(0).getDOMNode().className).toContain(' off');
expect(nameColumn.find('.ant-table-column-sorter-up').at(0).getDOMNode().className).toContain(' off');
});
// https://github.com/ant-design/ant-design/issues/12737
it('should toggle sort state when columns with non primitive properties are put in render', () => {
const testData = [
{ key: 0, name: 'Jack', age: 11 },
{ key: 1, name: 'Lucy', age: 20 },
{ key: 2, name: 'Tom', age: 21 },
{ key: 3, name: 'Jerry', age: 22 },
];
class TableTest extends React.Component {
state = {
pagination: {},
};
onChange = (pagination) => {
this.setState({ pagination });
}
render() {
const columns = [{
title: 'name',
dataIndex: 'name',
sorter: true,
render: text => text,
}];
const { pagination } = this.state;
return (
<Table
columns={columns}
pagination={pagination}
dataSource={testData}
onChange={this.onChange}
/>
);
}
}
const wrapper = mount(<TableTest />);
const nameColumn = wrapper.find('.ant-table-column-sorters').at(0);
expect(nameColumn.find('.ant-table-column-sorter-down').at(0).getDOMNode().className).toContain(' off');
expect(nameColumn.find('.ant-table-column-sorter-up').at(0).getDOMNode().className).toContain(' off');
// sort name
nameColumn.simulate('click');
expect(nameColumn.find('.ant-table-column-sorter-down').at(0).getDOMNode().className).toContain(' on');
expect(nameColumn.find('.ant-table-column-sorter-up').at(0).getDOMNode().className).toContain(' off');
// sort name
nameColumn.simulate('click');
expect(nameColumn.find('.ant-table-column-sorter-down').at(0).getDOMNode().className).toContain(' off');
expect(nameColumn.find('.ant-table-column-sorter-up').at(0).getDOMNode().className).toContain(' on');
// sort name
nameColumn.simulate('click');
expect(nameColumn.find('.ant-table-column-sorter-down').at(0).getDOMNode().className).toContain(' off');
expect(nameColumn.find('.ant-table-column-sorter-up').at(0).getDOMNode().className).toContain(' off');
});
// https://github.com/ant-design/ant-design/issues/12870
it('should toggle sort state when columns with key are put in render', () => {
const testData = [
{ key: 0, name: 'Jack', age: 11 },
{ key: 1, name: 'Lucy', age: 20 },
{ key: 2, name: 'Tom', age: 21 },
{ key: 3, name: 'Jerry', age: 22 },
];
class TableTest extends React.Component {
state = {
pagination: {},
};
onChange = (pagination) => {
this.setState({ pagination });
}
render() {
const columns = [{
title: 'name',
dataIndex: 'name',
sorter: true,
key: 'a',
style: {
fontSize: 18,
},
}];
const { pagination } = this.state;
return (
<Table
columns={columns}
pagination={pagination}
dataSource={testData}
onChange={this.onChange}
/>
);
}
}
const wrapper = mount(<TableTest />);
const nameColumn = wrapper.find('.ant-table-column-sorters').at(0);
expect(nameColumn.find('.ant-table-column-sorter-down').at(0).getDOMNode().className).toContain(' off');
expect(nameColumn.find('.ant-table-column-sorter-up').at(0).getDOMNode().className).toContain(' off');
// sort name
nameColumn.simulate('click');
expect(nameColumn.find('.ant-table-column-sorter-down').at(0).getDOMNode().className).toContain(' on');
expect(nameColumn.find('.ant-table-column-sorter-up').at(0).getDOMNode().className).toContain(' off');
// sort name
nameColumn.simulate('click');
expect(nameColumn.find('.ant-table-column-sorter-down').at(0).getDOMNode().className).toContain(' off');
expect(nameColumn.find('.ant-table-column-sorter-up').at(0).getDOMNode().className).toContain(' on');
// sort name
nameColumn.simulate('click');
expect(nameColumn.find('.ant-table-column-sorter-down').at(0).getDOMNode().className).toContain(' off');
expect(nameColumn.find('.ant-table-column-sorter-up').at(0).getDOMNode().className).toContain(' off');
});
});