Ant Design Table组件支持自定义筛选菜单,官网给出的 Demo 只能对当前页的数据进行过滤,而实际开发中往往都是远程数据源,因此需要改造下。
-
首先是 Table ,为方便阅读多余代码已清除:
<Table pagination={ Object.assign(pagination, { onChange: async (pageIndex: number, pageSize?: number) => { fetchData({pageIndex, pageSize}); } }) } columns={columns} dataSource={data}/> -
其中一列(
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>; } } -
查询数据函数
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 }>({}); -
搜索按钮点击后,
selectedKeys、confirm、dataIndex被传到事件处理函数handleSearch,handleSearch定义:function handleSearch(selectedKeys: any[], confirm: Function, dataIndex: string) { setSearchForm(prev => { let current = Object.assign({}, prev); current[dataIndex] = selectedKeys[0]; return current; }); setFilterCallback(() => confirm); }以上函数的逻辑是:
-
将过滤条件保存到
searchForm中。 -
将
confirm函数保存到filterCallback中,filterCallback定义如下:const [filterCallback, setFilterCallback] = useState<Function | null>(null); -
触发
filterCallback的监听并调用(即confirm函数):// useUpdateEffect 用法请参考 react-use useUpdateEffect(() => { if (filterCallback) { filterCallback(); } }, [filterCallback])使用
State保存confirm函数的原因是同一个useEffect中的 state 值是固定的,如果在setSearchForm后直接调用confirm,会导致onChange函数中fetchData函数拿到的是修改前的searchForm。 -
confirm函数执行后,触发onChange函数,进而调用fetchData向服务端发起请求并更新列表的数据。
-