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

React Table:如何实现按Vendor分组的可折叠行?

React Table实现Vendor可折叠分组行方案

问题背景

给定以下TypeScript数据结构,需要实现带Vendor(如Vendor1、Vendor2)可折叠分组行的React Table:

export type VendorContent = {
  id: number;
  name: string;
  user_name: string;
  dob: string;
};

export type VendorData = {
  vendor: string;
  rows: VendorContent[];
};

通过<DataTable defaultData={vendorData} />传入数据,当前代码因扁平化数据丢失分组信息,无法实现分组折叠功能,尝试过直接传入原数据、getSubRows、Header Groups均未满足需求。

解决方案

利用React Table的**展开折叠(useExpanded)和子行获取(getSubRows)**能力,结合自定义分组行渲染,实现需求:

1. 调整数据结构,保留分组关联

不再扁平化数据,而是将每个Vendor项作为顶层行,关联对应的子行数据:

const [data, setData] = React.useState(() =>
  defaultData.map(item => ({
    vendor: item.vendor,
    subRows: item.rows,
    isGroupRow: true // 标记为分组行,用于后续渲染区分
  }))
);

2. 配置React Table插件与参数

引入useExpanded插件处理展开折叠状态,同时定义getSubRows函数指定子行来源:

import { useReactTable, getCoreRowModel, useExpanded, getSubRows } from '@tanstack/react-table';

// ...

const table = useReactTable({
  data,
  columns,
  getCoreRowModel: getCoreRowModel(),
  useExpanded, // 启用展开折叠功能
  getSubRows: row => row.subRows || [], // 指定子行获取逻辑
});

3. 修改列定义,添加分组列

新增分组列用于渲染展开按钮和Vendor名称,其他列保持原有配置:

const columns = [
  columnHelper.display({
    id: 'group',
    header: '',
    cell: ({ row }) => {
      if (row.original.isGroupRow) {
        return (
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            {/* 展开/折叠切换按钮 */}
            <button onClick={() => row.toggleExpanded()}>
              {row.getIsExpanded() ? '▼' : '▶'}
            </button>
            <strong>{row.original.vendor}</strong>
          </div>
        );
      }
      return null; // 数据行该列留空
    },
  }),
  columnHelper.accessor('name', {
    header: () => 'Name',
    cell: (info) => info.renderValue(),
  }),
  columnHelper.accessor('user_name', {
    header: () => 'User name',
    cell: (info) => info.renderValue(),
  }),
  columnHelper.accessor('dob', {
    header: () => 'DOB',
    cell: (info) => info.renderValue(),
  }),
  columnHelper.display({
    id: 'actions',
    cell: (props) => <p>test</p>,
  }),
];

4. 渲染表格时处理分组行跨列

在tbody渲染逻辑中,让分组行的首个单元格跨所有可见列,保证布局美观:

<table>
  <thead>
    {table.getHeaderGroups().map(headerGroup => (
      <tr key={headerGroup.id}>
        {headerGroup.headers.map(header => (
          <th key={header.id}>{header.renderHeader()}</th>
        ))}
      </tr>
    ))}
  </thead>
  <tbody>
    {table.getRowModel().rows.map(row => (
      <tr key={row.id}>
        {row.getVisibleCells().map((cell, index) => {
          if (row.original.isGroupRow && index === 0) {
            // 分组行跨列渲染
            return (
              <td colSpan={row.getVisibleCells().length} key={cell.id}>
                {cell.renderCell()}
              </td>
            );
          }
          return <td key={cell.id}>{cell.renderCell()}</td>;
        })}
      </tr>
    ))}
  </tbody>
</table>

关键说明

  • 通过isGroupRow标记区分分组行与数据行,实现差异化渲染
  • row.toggleExpanded()和row.getIsExpanded()用于控制和判断展开状态
  • getSubRows告诉React Table如何从顶层行获取子行数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:03:30