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

如何在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}, 
]

初始渲染表格

idlabelcost
0Parent Item 12
1Child Item 11
2Child Item 21
3Parent Item 21.5
4Child Item 11.5

排序后预期效果

按「Cost(从低到高)」排序后,父行排序,子行跟随父行位置,结果如下:

idlabelcost
3Parent Item 21.5
4Child Item 11.5
0Parent Item 12
1Child Item 11
2Child Item 21

当前尝试代码

我写了部分排序逻辑,但不知道如何处理子行:

{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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:50:32