如何在Ant Design表格移除列时自动清除对应过滤器?
问题
我在基于ReactJS(TypeScript)、使用Ant Design 4.12.2的项目中,实现了一个展示多条记录数据的表格,支持通过带树形选项的弹出框添加或移除列,部分列带有过滤器功能。
目前功能整体正常,但存在以下问题:激活某列的过滤器后移除该列,列会被成功移除,但对应的过滤器并未失效,表格显示的记录数无法恢复到过滤前的状态;重新添加该列时,之前激活的过滤器仍处于生效状态。
我曾尝试在useEffect中将列的filteredValue设为null,但没有效果;用于调试的clear按钮仅在列可见时能清除过滤器,列移除后该按钮无效,重新添加列时过滤器状态也存在异常。
编辑:我已参考相关文章更新代码,加入了对filteredInfo的跟踪与更新,但问题依旧存在。
代码示例
const isPresent = <T,>(t: T | undefined | null): t is T => t != null; interface User { username: string, status: string } const ReportItemsTable: React.FC = () => { const allColumnOptions = [ { key: "username", title: "Username" }, { key: "status", title: "Status" } ]; const items: User[] = [ { status: "one", username: "Piet" }, { status: "two", username: "Saar" }, { status: "one", username: "Jan" }, { status: "two", username: "Klaas" }, { status: "one", username: "Maartje" }, { status: "three", username: "Sjeng" }, { status: "one", username: "Elke" }, { status: "two", username: "Twan" }, { status: "one", username: "An" }, { status: "three", username: "Nel" }, ]; const [filteredInfo, setFilteredInfo] = useState<Record<string, FilterValue | null>>({}); const possibleColumns: ColumnType<User>[] = [ { title: "Username", key: "username", dataIndex: "username", sorter: (a: User, b: User) => a.username.localeCompare(b.username), render: (userName: string) => (<>{userName}</>) }, { title: "Status", key: "status", dataIndex: "status", filteredValue: filteredInfo && filteredInfo["status"], filters: [ { text: "One", value: "one" }, { text: "Two", value: "two" }, { text: "Three", value: "three" }, ], onFilter: (value: ColumnFilterValue, user: User) => user.status === value, sorter: (a: User, b: User) => a.status.localeCompare(b.status), render: (status: string) => (<>{status}</>) } ]; // Note that selectedColumns is controlled by checkedKeys. selectedColumns should not be modified directly. const [checkedKeys, setCheckedKeys] = useState<Key[] | { checked: Key[]; halfChecked: Key[]; }>([]); const [selectedColumns, setSelectedColumns] = useState<ColumnType<User>[]>(possibleColumns); const getTreeData = (allOptions: DataNode[]): DataNode[] => { return [{ key: "masterKey", title: "(de)select all", children: [...allOptions] }]; }; // The useEffect below was originally only in charge of checking // whether the checkedKeys had changed and accordingly adding or // removing columns from the table. It was expanded to set the // filteredValue to null if the column was unchecked. useEffect(() => { setFilteredInfo(filteredInfo => { const newFilteredInfo = {...filteredInfo}; const visibleKeys = Array.isArray(checkedKeys) ? checkedKeys : checkedKeys.checked; const invisibleKeys = possibleColumns.map(column => column.key).filter(isPresent).filter(columnKey => !visibleKeys.includes(columnKey)); invisibleKeys.forEach(key => delete newFilteredInfo[key]); return newFilteredInfo; }); if (Array.isArray(checkedKeys)) { setSelectedColumns(possibleColumns .map(column => { if (!isPresent(column.key)) return column; if (!checkedKeys.includes(column.key)) { return { ...column, filteredValue: null } } return column; }) .filter(column => checkedKeys .map(checkedKey => checkedKey.toString()) .includes(column.key?.toString() ?? ""))); } else { setSelectedColumns(possibleColumns .map(column => { if (!isPresent(column.key)) return column; if (!checkedKeys.checked.includes(column.key)) { return { ...column, filteredValue: null } } return column; }) .filter(column => checkedKeys.checked .map(checkedKey => checkedKey.toString()) .includes(column.key?.toString() ?? ""))); } }, [checkedKeys]); const filterTree = <Tree key={"columnfilter"} checkable defaultExpandedKeys={["masterKey"]} checkedKeys={checkedKeys} selectable={false} onCheck={checkedKeys => { setCheckedKeys(checkedKeys); }} treeData={getTreeData(allColumnOptions)} /> ; const columnFilterButton = <Popover placement="bottom" title="Select columns" content={filterTree} trigger="click"> <Tooltip title="Select columns"> <Button icon={<ViewWeekOutlinedIcon sx={{ fontSize: 17, marginTop: "2.5px" }}></ViewWeekOutlinedIcon>}> </Button> </Tooltip> </Popover> ; return ( <> <Row style={{paddingTop: "10px", paddingBottom: "10px"}}> <Col span={24} style={{ textAlign: "left" }}> <Space> <Button.Group> {columnFilterButton} </Button.Group> </Space> </Col> </Row> <Table onChange={(pagination, filters) => setFilteredInfo(filters)} columns={selectedColumns} dataSource={items} size="middle" /> <button onClick={() => { setFilteredInfo({}); setSelectedColumns(selectedColumns.map(column => { return { ...column, filteredValue: null }; })); } }>clear</button> </> ); }; export default ReportItemsTable;
内容的提问来源于stack exchange,提问作者lonkelo
相关产品推荐
相关产品推荐

