react-antd table中服务端排序的问题

使用框架

umi+dva+antd

问题

当使用服务端排序发送一个action之后。第一次排序的order顺序是descend,随后就一直是descend不管怎么点击切换都不行

排查过程

查看了antd table中的源代码在第610行开始是切换排序顺序的源代码

        key: 'toggleSortOrder',
        value: function toggleSortOrder(column) {
            if (!column.sorter) {
                return;
            }
            
            var _state = this.state,
                sortOrder = _state.sortOrder,
                sortColumn = _state.sortColumn;
            // 只同时允许一列进行排序,否则会导致排序顺序的逻辑问题
            var newSortOrder = void 0;
            // 切换另一列时,丢弃 sortOrder 的状态
            var oldSortOrder = sortColumn === column || shallowEqual(sortColumn, column) ? sortOrder : undefined;
            // 切换排序状态,按照降序/升序/不排序的顺序
            if (!oldSortOrder) {
                newSortOrder = 'descend';
            } else if (oldSortOrder === 'descend') {
                newSortOrder = 'ascend';
            } else {
                newSortOrder = undefined;
            }
            var newState = {
                sortOrder: newSortOrder,
                sortColumn: newSortOrder ? column : null
            };
            // Controlled
            if (this.getSortOrderColumns().length === 0) {
                this.setState(newState);
            }
            var onChange = this.props.onChange;

            if (onChange) {
                onChange.apply(null, this.prepareParamsArguments(_extends({}, this.state, newState)));
            }
        }

发现问题

在代码的第二行注释中发现了sortColumn === column一直返回的是false所以每一次的newSortOrder都为true导致不管怎么点击切换最后的排序结果始终是descend

尝试解决

sortColumn column对象中的每一个属性拆分出来一个一个对比。

clipboard.png

对比后的结论:除了title字段不全等以外其他的都全等

继续深入对比title字段

clipboard.png

对比后的结论:除了_store字段不全等以外,其他的都全等。下面贴出_store字段的内容

clipboard.png

贴出title的代码,需要注意的是title使用了国际化(猜测问题就是出现在国际化上面)

{
    title: <FormattedMessage id="K_AMOUNT" />,
    dataIndex: "amount",
    render: text => {
        return (
            <span id="gac_amount">
                {fmoney(qGacToGac(text), 3)} GAC
            </span>
        );
    },
    sorter: true
}

寻求一个解决办法

阅读 8.1k
3 个回答

已经解决了,问题是通过发送action后_store中重新创建了一个新的对象(注意是创建不是复制的,导致他们的引用不同)所以不全等。我通过修改了antd源码并且重新编译后成功解决了此问题:

var oldSortOrder = (sortColumn ? sortColumn.dataIndex : {}) === (column ? column.dataIndex : {}) || shallowEqual(sortColumn, column) ? sortOrder : undefined;

我们只要保证当前切换的是同一列数据就可以了所以判断他们的dataIndex也是可以的

新手上路,请多包涵

you can update antd to 3.11.0 version

加个 key,或者把 columns 从 render 中拿出来。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题