React Table如何按条件取消指定行复选框的选中状态
问题描述
在项目中使用react-table组件实现带行复选框的表格,需求为点击指定按钮时,取消数据Id=1、Id=2的两行的复选框选中状态,其余行保持原有选中状态不变。
现有实现代码如下:
const UsersTable = () => { const [tableData, setTableData] = useState(initialData); const columns = useMemo(() => COLUMNS, []); const data = useMemo(() => tableData, [tableData]); const handleValues = (processeddata) => { console.log(processeddata); // 此处需要实现取消指定行选中的逻辑 }; return ( <> <Table columns={columns} data={data} goUp={handleValues} /> </> ); }; const Table = ({ columns, data, goUp }) => { const { getTableProps, headerGroups, rows, prepareRow, selectedFlatRows, state: { selectedRowIds }, state, setGlobalFilter } = useTable({ columns, data }, useGlobalFilter, useRowSelect, (hooks) => { hooks.visibleColumns.push((col) => [ { id: "selection", Header: ({ getToggleAllRowsSelectedProps }) => ( <TableCheckbox {...getToggleAllRowsSelectedProps()} /> ), Cell: ({ row }) => <Checkbox {...row.getToggleRowSelectedProps()} /> }, ...col ]); }); const enableSelectedUser = (event) => { goUp(selectedFlatRows); console.log(selectedFlatRows); }; const { globalFilter } = state; return ( <> <button onClick={enableSelectedUser}> Click me! to unclick the checkbox </button> <TableContainer> <MUITable {...getTableProps()}> <TableHead> {headerGroups.map((headerGroup) => ( <TableRow {...headerGroup.getHeaderGroupProps()}> {headerGroup.headers.map((column) => ( <TableCell {...column.getHeaderProps()}> {column.render("Header")} </TableCell> ))} </TableRow> ))} </TableHead> <TableBody> {rows.map((row) => { prepareRow(row); return ( <TableRow {...row.getRowProps()}> {row.cells.map((cell) => cell.column.id === "selection" ? ( <TableCell {...cell.getCellProps()}> {cell.render("Cell")} </TableCell> ) : ( <TableCell {...cell.getCellProps()}> {cell.render("Cell")} </TableCell> ) )} </TableRow> ); })} </TableBody> </MUITable> </TableContainer> </> ); };
当前需要实现的效果:选中若干复选框后点击顶部按钮,Id为1、2的两行自动取消选中。
实现步骤
react-table的useRowSelect插件内置了行选中状态的操作方法,不需要额外维护选中状态,直接调用内置方法即可实现需求:
- 补充解构状态操作方法
在useTable的返回值中,额外取出toggleRowSelected(切换单行选中状态)和setSelectedRowIds(直接修改选中行id集合)两个方法,同时建议新增getRowId配置,用数据本身的唯一id作为行id,避免排序/过滤后索引错位:const { getTableProps, headerGroups, rows, prepareRow, selectedFlatRows, state: { selectedRowIds }, state, setGlobalFilter, toggleRowSelected, setSelectedRowIds // 批量修改选中状态时使用 } = useTable( { columns, data, getRowId: (row) => row.id // 绑定数据唯一主键作为行id }, useGlobalFilter, useRowSelect, (hooks) => { hooks.visibleColumns.push((col) => [ { id: "selection", Header: ({ getToggleAllRowsSelectedProps }) => ( <TableCheckbox {...getToggleAllRowsSelectedProps()} /> ), Cell: ({ row }) => <Checkbox {...row.getToggleRowSelectedProps()} /> }, ...col ]); } ); - 修改按钮点击逻辑
推荐直接操作选中状态集合实现,逻辑更清晰性能更好:
如果需要动态匹配行(比如后续要调整取消选中的规则),可以通过遍历rows匹配数据id的方式获取行id再操作:const enableSelectedUser = (event) => { setSelectedRowIds(prevSelectedIds => { // 拷贝原有选中状态,避免直接修改state const nextSelectedIds = { ...prevSelectedIds }; // 删除id为1、2的两个行的选中标记 delete nextSelectedIds["1"]; delete nextSelectedIds["2"]; return nextSelectedIds; }); // 原有回调逻辑保留,若需要拿到最新的选中行,可在useEffect中监听selectedRowIds变化后再触发 goUp(selectedFlatRows); };const enableSelectedUser = (event) => { // 找到所有数据id为1、2的行 const needUnselectRows = rows.filter(row => row.original.id === 1 || row.original.id === 2 ); // 逐个设置为未选中状态,第二个参数传false代表强制取消选中 needUnselectRows.forEach(row => { toggleRowSelected(row.id, false); }); goUp(selectedFlatRows); };
注意:如果没有配置
getRowId,react-table默认用行在当前显示列表中的索引作为行id,一旦做了排序、过滤、分页操作,行索引会和原始数据id不匹配,会导致取消选中的行错误。
内容的提问来源于stack exchange,提问作者Ganesh
相关产品推荐
相关产品推荐

