diff --git a/components/table/Table.tsx b/components/table/Table.tsx index c7b0579837..75113ded1d 100755 --- a/components/table/Table.tsx +++ b/components/table/Table.tsx @@ -358,6 +358,17 @@ export default class Table extends React.Component, TableState< }; } + isSameColumn(a: ColumnProps | null, b: ColumnProps | 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) { if (!column.sorter) { return; @@ -366,8 +377,7 @@ export default class Table extends React.Component, 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'; diff --git a/components/table/__tests__/Table.sorter.test.js b/components/table/__tests__/Table.sorter.test.js index b8b896ae00..d2d5c90c96 100644 --- a/components/table/__tests__/Table.sorter.test.js +++ b/components/table/__tests__/Table.sorter.test.js @@ -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 ( + + ); + } + } + + const wrapper = mount(); + 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 ( +
+ ); + } + } + + const wrapper = mount(); + 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'); + }); });