关于antd Table组件 Filter 筛选数据功能的思考和优化

8,543 阅读3分钟

业务背景:

今天拿到了一个表格数据展示的需求,由于业务需要对数据进行选择过滤并且原来已经选用了 antd 中的 Table,所以选择了使用antd Table 自带的过滤功能。

关于过滤方式

首先在表格中进行数据的过滤和筛选大概有两种方式:

  • 第一种是在后端进行数据的筛选,即做查询关键字的处理,当数据量较大,服务器压力较小的情况下进行选用。

  • 第二种是在前端进行数据的筛选,即在前端对数据进行处理后显示,对客户端页面渲染压力较小的情况下进行选用,它还有一点优势就是减少了对后端的http请求,可以降低对后台服务器的压力

我们这里是选用了第二种方式进行数据筛选。

TABLE的优化

在实践中发现antd table的逻辑是对整页的数据进行筛选,然后在该页只余下当前页面符合数据筛选逻辑,这样会导致所有页面即使该页出现可能如下图只出现一条数据却有32页的情况,并且这一条数据可能出现在32页中的任意一页,这对于用户是极其不友好的,因此我和组长商量后决定修改该方法

这里贴上antd Table本地筛选的示例代码改写进行演示 ---(公司业务代码保密,不允许展示)

import { Table } from 'antd';

const columns = [
  {
    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`
  },
  {
    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',
      },
    ],
    filterMultiple: false,
    onFilter: (value, record) => record.address.indexOf(value) === 0,
    sorter: (a, b) => a.address.length - b.address.length,
    sortDirections: ['descend', 'ascend'],
  },
];
const data = [
  {
    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',
  },//假装有好几百页
];
let showData = [];
function onChange(pagination, filters, sorter, extra) {
  console.log('params', pagination, filters, sorter, extra);
  showData = [];
  filters.name.map((value, index) => {
  		for (let i = 0; i < data.length; i++){
			if (data[i].name.indexof(value) === 0 ){
                             showData.push(data[i]);
            }
    	}
  }
} //将过滤的方法转变到这里来
/* 
    - 第一步 要将所有的数据是要保存到一个初始大数组里面,因为后面不希望再需要请求数据
    - 第二步 将初始大数据进行对比过滤,将其赋值给显示数组
    - 第三步 刷新页面
*/
ReactDOM.render(<Table columns={columns} dataSource={showData} onChange={onChange} />, mountNode);

总结

通过上述更改就可以实现将所有数据筛选后放到前页进行统一展示,减少用户逐页寻找数据的麻烦,提高用户体验,并且减少了后端的请求压力。

当然上述非常重要的一点就是不是所有业务都是适合在前端进行数据筛选,只有特定的业务背景下:展示数据量小,服务器压力大,并且用户看完一半以上数据量情况频繁的情况下,使用前端进行数据筛选也不失为一种可行的数据优化方案。