🌲系列一:跟着官方示例学习 @tanStack-table --- Basic
🌲系列二:跟着官方示例学习 @tanStack-table --- Header Groups
🌲系列三:跟着官方示例学习 @tanStack-table --- Column Filters
🌲系列四:跟着官方示例学习 @tanStack-table --- Column Ordering
🌲系列五:跟着官方示例学习 @tanStack-table ---Sticky Column Pinning
🌲系列六:跟着官方示例学习 @tanStack-table --- Column Sizing
🧐 展开是啥?有啥用?
展开行(Row Expanding) 是一种让每一行可以“展开/折叠”的功能,常用于:
-
显示子表格或子行(Tree/Table 嵌套结构)
-
展示某一行的详细信息(比如某用户的个人资料)
-
构建像“树形结构”那样的数据层级
想象一个组织结构图,每一行都能点开,看下面还有谁,这不就很赞嘛!
🛠️ 开启展开功能的正确姿势
要用展开功能,首先得在 useReactTable 里配置这三大件:
const table = useReactTable({
data,
columns,
// 1. 提供展开状态
state: {
expanded,
},
// 2. 当展开变化时,更新状态
onExpandedChange: setExpanded,
// 3. 告诉表格哪里有子行
getSubRows: row => row.subRows,
getCoreRowModel: getCoreRowModel(),
// 关键:启用展开模型
getExpandedRowModel: getExpandedRowModel(),
})
👆 展开按钮 & 缩进的魔法操作
我们希望用户能点击按钮来展开每一行
cell: ({ row, getValue }) => (
<div style={{ paddingLeft: `${row.depth * 2}rem` }}>
<div>
{row.getCanExpand() ? (
<button onClick={row.getToggleExpandedHandler()}>
{row.getIsExpanded() ? '👇' : '👉'}
</button>
) : (
'🔵'
)}{' '}
{getValue()}
</div>
</div>
)
🧩 分析一下:
-
row.depth: 当前行的嵌套层级,用它加点paddingLeft,实现层级缩进视觉效果 -
row.getCanExpand()返回这个行是不是“可以展开”,比如有没有子项 -
row.getIsExpanded()返回当前行是否已展开 -
row.getToggleExpandedHandler()返回一个onClick处理函数,点击后展开或折叠这一行。
是不是有点像点击目录树节点,内容就展开啦?🐿️
📦 展开所有行
甚至可以点击一个按钮展开/折叠所有行!
<button onClick={table.getToggleAllRowsExpandedHandler()}>
{table.getIsAllRowsExpanded() ? '👇' : '👉'}
</button>
🔔 温馨提示
为可以正常地展开和关闭,需要保持这样的数据结构
[
{
firstName: 'Alice',
// getSubRows: row => row.subRows 需要一一对应
// 如果数组中子结构的key值为 children, 那么对应 row => row.children
subRows: [
{ firstName: 'Alice Jr.', subRows: [...] },
{ firstName: 'Bob Jr.' }
]
},
//...
]
🔔 对官方示例代码可能存在一些删减的情况
代码地址🔗:Gitee
官方代码地址🔗: @tanStack/react-table
自定义展开内容(Custom Expanding UI)
有时候,subRows 太局限了。
你可能想这样做:
-
展开一行后展示用户详情卡片
-
展示异步加载的数据
-
加一段说明文字、图表、图片甚至评论列表!
📺 渲染你自己的展开内容
我们需要检测某一行是否已展开(row.getIsExpanded()),然后在表格中手动插入一行渲染展开区域,比如:
<tbody>
{table.getRowModel().rows.map(row => {
return (
<Fragment key={row.id}>
<tr>
{/* first row is a normal row */}
{row.getVisibleCells().map(cell => {
return (
<td key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</td>
)
})}
</tr>
{/* 👇重点看这里 */}
{row.getIsExpanded() && (
<tr>
{/* 2nd row is a custom 1 cell row */}
<td colSpan={row.getVisibleCells().length}>
{renderSubComponent({ row })}
</td>
</tr>
)}
</Fragment>
)
})
}
</tbody >
这只是个示例,理论上这里可以书写任何你期望展开之后,看到的内容✨✨
const renderSubComponent = ({ row }: { row: Row<Person> }) => {
return (
<pre style={{ fontSize: '10px' }}>
<code>{JSON.stringify(row.original, null, 2)}</code>
</pre>
)
}
🔔 对官方示例代码可能存在一些删减的情况
代码地址🔗:Gitee
官方代码地址🔗: @tanStack/react-table