实现使用远程数据源的Ant Design Table自定义筛选

2,881 阅读1分钟

Ant Design Table组件支持自定义筛选菜单,官网给出的 Demo 只能对当前页的数据进行过滤,而实际开发中往往都是远程数据源,因此需要改造下。

  1. 首先是 Table ,为方便阅读多余代码已清除:

    <Table pagination={
        Object.assign(pagination, {
           onChange: async (pageIndex: number, pageSize?: number) => {
               fetchData({pageIndex, pageSize});
           }
       })
    }
    columns={columns} dataSource={data}/>
    
  2. 其中一列(Column)定义:

    {
        title: '姓名',
        dataIndex: 'name',
        filterDropDown: function({setSelectedKeys, selectedKeys, confirm, clearFilters}: any) {
            return <div>
                <Input onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}/>
                <Button onClick={() => handleSearch(selectedKeys, confirm, dataIndex)}>
                    搜索
                </Button>
            </div>;
        }
    }
    
  3. 查询数据函数fetchData定义:

    async function fetchData(pager?: Pager) {
        let gridData = await getGridData({
            url: props.url,
            pager: pager,
            searchForm: searchForm
        });
        setData(gridData.data);
        setPagination(gridData.pagination);
    }
    

    可以看到查询数据时会向服务端发送一个searchForm对象,searchForm对象保存的是当前全部过滤条件:

    const [searchForm, setSearchForm] = useState<{ [key: string]: string }>({});
    
  4. 搜索按钮点击后,selectedKeysconfirmdataIndex被传到事件处理函数handleSearchhandleSearch定义:

    function handleSearch(selectedKeys: any[], confirm: Function, dataIndex: string) {
        setSearchForm(prev => {
            let current = Object.assign({}, prev);
            current[dataIndex] = selectedKeys[0];
            return current;
        });
        setFilterCallback(() => confirm);
    }
    

    以上函数的逻辑是:

    1. 将过滤条件保存到searchForm中。

    2. confirm函数保存到filterCallback中,filterCallback定义如下:

      const [filterCallback, setFilterCallback] = useState<Function | null>(null);
      
    3. 触发filterCallback的监听并调用(即confirm函数):

      // useUpdateEffect 用法请参考 react-use
      useUpdateEffect(() => {
          if (filterCallback) {
              filterCallback();
          }
      }, [filterCallback])
      

      使用 State 保存confirm函数的原因是同一个useEffect中的 state 值是固定的,如果在setSearchForm后直接调用confirm,会导致onChange函数中fetchData函数拿到的是修改前的searchForm

    4. confirm函数执行后,触发onChange函数,进而调用fetchData向服务端发起请求并更新列表的数据。