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

如何实现React表格仅被点击行触发Collapse折叠效果

问题根因

所有表格行共用了同一个布尔类型的open状态:

  • 任意行的按钮点击时,修改的都是这同一个全局状态
  • 所有行的Collapse组件的展开控制属性in都绑定了这个open值,因此会同步触发展开/收起逻辑,无法实现单行独立控制。
修复方案

根据交互需求二选一即可:

方案1:单展开模式(同一时间仅允许展开一行)

不再存储布尔值,改为存储当前展开行的唯一id,默认值为null(默认无展开行)。

  1. 替换原有状态定义:
// 替换原来的 const [open, setOpen] = useState(false)
const [openRowId, setOpenRowId] = useState<string | number | null>(null);
  1. 修改行渲染逻辑,仅当当前行id和存储的展开id一致时,才触发展开、渲染对应方向的图标:
{data.map((dataRow) => (
  <TableRow
    key={dataRow.id}
    title="tableRow"
    className={classes.tableRow}
  >
    <TableCell className={classes.tableCell}>
      <IconButton 
        size="small" 
        onClick={() => {
          // 点击当前已展开的行则收起,否则展开当前行、自动收起其他行
          setOpenRowId(openRowId === dataRow.id ? null : dataRow.id)
        }}
      >
        {openRowId === dataRow.id ? <ArrowDropDownIcon /> : <ArrowDropUpIcon />}
      </IconButton>
      {dataRow.id}
      <Collapse in={openRowId === dataRow.id} timeout="auto" unmountOnExit>
        <Box margin={1}>
          <Typography variant="h6" gutterBottom component="div">
            History
          </Typography>
        </Box>
      </Collapse>
    </TableCell>
    <TableCell className={classes.tableCell}>
      {dataRow.name}
    </TableCell>
    <TableCell align="left" className={classes.tableCell}>
      {dataRow.lastName}
    </TableCell>
  </TableRow>
))}

方案2:多展开模式(支持同时展开多行)

存储所有处于展开状态的行id集合,点击时切换当前行id在集合中的存在状态即可。

  1. 替换原有状态定义:
const [openRowIds, setOpenRowIds] = useState<Set<string | number>>(new Set());
  1. 修改行渲染逻辑:
<IconButton 
  size="small" 
  onClick={() => {
    setOpenRowIds(prev => {
      const newOpenSet = new Set(prev);
      // 已展开则移除id(收起),未展开则加入id(展开)
      if (newOpenSet.has(dataRow.id)) {
        newOpenSet.delete(dataRow.id)
      } else {
        newOpenSet.add(dataRow.id)
      }
      return newOpenSet
    })
  }}
>
  {openRowIds.has(dataRow.id) ? <ArrowDropDownIcon /> : <ArrowDropUpIcon />}
</IconButton>
{/* Collapse 组件的in属性同步修改为 */}
<Collapse in={openRowIds.has(dataRow.id)} timeout="auto" unmountOnExit>
  {/* 折叠内容保持不变 */}
</Collapse>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:01:30