You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在react-table的useRowSelect中实现条件控制行不可选功能

react-table useRowSelect 不可选行实现方案

方案1:重写内置选择方法(侵入性最低)

适合不需要完全接管选中状态的场景,基于原有useRowSelect逻辑扩展即可

  • 首先定义行可选判定规则,可根据业务需求自定义:
// 示例:status为disabled的行不可选,返回true表示行可选择
const isRowSelectable = (row) => row.original.status !== 'disabled'
  • 实例化表格时,通过hooks重写默认的toggleRowSelected(单行选择)和toggleAllRowsSelected(全选)逻辑:
const {
  getTableProps,
  getTableBodyProps,
  headerGroups,
  rows,
  prepareRow,
  toggleRowSelected: originalToggleRowSelected,
} = useTable(
  { columns, data },
  useRowSelect,
  (hooks) => {
    // 重写单行选择:不可选行直接跳过选择逻辑
    hooks.toggleRowSelected.push((originalFn, row, isSelected) => {
      if (!isRowSelectable(row)) return
      originalFn(row, isSelected)
    })
    // 重写全选:只选中符合条件的行
    hooks.toggleAllRowsSelected.push((originalFn, isSelected) => {
      rows.forEach(row => {
        if (isRowSelectable(row)) {
          originalToggleRowSelected(row.id, isSelected)
        }
      })
    })
  }
)
  • 渲染时给不可选行的选择框加禁用状态,同步UI提示:
// 行选择列Cell渲染
Cell: ({ row }) => (
  <input
    type="checkbox"
    checked={row.isSelected}
    onChange={row.toggleRowSelected}
    disabled={!isRowSelectable(row)}
  />
)
// 头部全选框渲染,修正全选/半选状态统计逻辑
Header: ({ getToggleAllRowsSelectedProps }) => {
  const selectableRows = rows.filter(isRowSelectable)
  const selectedCount = selectableRows.filter(r => r.isSelected).length
  return (
    <input
      type="checkbox"
      {...getToggleAllRowsSelectedProps()}
      checked={selectableRows.length > 0 && selectedCount === selectableRows.length}
      indeterminate={selectedCount > 0 && selectedCount < selectableRows.length}
    />
  )
}

方案2:受控模式实现(灵活度最高)

适合选择逻辑非常复杂的场景,完全自己控制选中状态

  • 开启manualSelection配置,将选中状态存在组件state中:
const [selectedRowIds, setSelectedRowIds] = useState({})

const tableInstance = useTable(
  {
    columns,
    data,
    manualSelection: true,
    selectedRowIds,
  },
  useRowSelect
)
  • 自定义单行、全选触发逻辑:
// 单行点击
const handleToggleRow = (row) => {
  if (!isRowSelectable(row)) return
  setSelectedRowIds(prev => ({
    ...prev,
    [row.id]: !prev[row.id]
  }))
}
// 全选点击
const handleToggleAll = (isSelectAll) => {
  const newSelected = {}
  if (isSelectAll) {
    tableInstance.rows.forEach(row => {
      if (isRowSelectable(row)) newSelected[row.id] = true
    })
  }
  setSelectedRowIds(newSelected)
}
  • 渲染选择框时绑定自定义的触发方法即可。

注意事项

  • 所有选中状态统计(比如已选数量、全选判定)都需要排除不可选行,避免出现状态显示异常
  • 不可选行建议额外增加灰化、tooltip提示等样式优化,降低用户理解成本

内容的提问来源于stack exchange,提问作者Liran H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 05:06:09