如何在Ant Design表格中对带父行的分组行进行排序?
React + Ant Design 分组表格排序问题
需求说明
用React和Ant Design构建表格时,需要保持行的父子分组结构:子项必须始终位于对应父项下方。排序表格时,仅基于父行的数据进行排序,子行不参与排序,始终跟随对应父行的位置。
示例数据
const data = [ {id: 0, label: "Parent Item 1", cost: 2, parentId: null, isParent: true}, {id: 1, label: "Child Item 1", cost: 1, parentId: 0, isParent: false}, {id: 2, label: "Child Item 2", cost: 1, parentId: 0, isParent: false}, {id: 3, label: "Parent Item 2", cost: 1, parentId: null, isParent: true}, {id: 4, label: "Child Item 1", cost: 1, parentId: 3, isParent: false}, ]
初始渲染表格
| id | label | cost |
|---|---|---|
| 0 | Parent Item 1 | 2 |
| 1 | Child Item 1 | 1 |
| 2 | Child Item 2 | 1 |
| 3 | Parent Item 2 | 1.5 |
| 4 | Child Item 1 | 1.5 |
排序后预期效果
按「Cost(从低到高)」排序后,父行排序,子行跟随父行位置,结果如下:
| id | label | cost |
|---|---|---|
| 3 | Parent Item 2 | 1.5 |
| 4 | Child Item 1 | 1.5 |
| 0 | Parent Item 1 | 2 |
| 1 | Child Item 1 | 1 |
| 2 | Child Item 2 | 1 |
当前尝试代码
我写了部分排序逻辑,但不知道如何处理子行:
{sorter: (a, b) => { if(a.isParent && b.isParent){ return a.cost - b.cost; } else { // one or more rows is child, not sure what to do here... } }}
需要一个可传入Array.prototype.sort()的函数,仅能使用a、b两个行参数。
解决方案
步骤1:提前构建行映射表
先在组件中用useMemo创建一个id到行对象的映射,方便快速查找父行:
import { useMemo } from 'react'; // 假设data是组件的props或状态 const rowMap = useMemo(() => { return data.reduce((map, row) => { map[row.id] = row; return map; }, {}); }, [data]);
步骤2:编写完整排序函数
const sorter = (a, b) => { // 获取当前行的排序基准父行:子行取父行,父行取自身 const getBaseRow = (row) => { return row.isParent ? row : rowMap[row.parentId]; }; const baseA = getBaseRow(a); const baseB = getBaseRow(b); // 若两行属于同一个父组,保持原始相对顺序 if (baseA.id === baseB.id) { return 0; } // 基于基准父行的cost字段排序 return baseA.cost - baseB.cost; };
逻辑说明
- 不管当前行是父还是子,都统一以其所属的父行作为排序基准
- 当两行属于同一父组时,返回0保持它们的原始相对位置,符合需求
- 利用提前构建的
rowMap,父行查找操作是O(1),不会影响性能
内容的提问来源于stack exchange,提问作者Robert Hosking
相关产品推荐
相关产品推荐

