列排序指南

示例

想跳过直接看实现吗?查看这些示例

API

列排序 API

列排序指南

默认情况下,列按照它们在 columns 数组中定义的顺序排序。但是,你可以使用 columnOrder 状态手动指定列顺序。列固定和分组等其他功能也可能影响列顺序。

影响列顺序的因素

有 3 个表格功能可以重新排序各列,它们按以下顺序发生

  1. 列固定 - 如果启用固定,列将分为左侧固定列、中间(未固定)列和右侧固定列。
  2. 手动 列排序 - 应用手动指定的列顺序。
  3. 分组 - 如果启用分组,分组状态处于活动状态,并且 tableOptions.groupedColumnMode 设置为 'reorder' | 'remove',则分组列将重新排序到列流的开头。

注意: 如果与列固定结合使用,columnOrder 状态只会影响未固定的列。

列顺序状态

如果你不提供 columnOrder 状态,TanStack Table 将只使用 columns 数组中列的顺序。但是,你可以将字符串列 ID 数组提供给 columnOrder 状态,以指定列的顺序。

默认列顺序

如果你只需要指定初始列顺序,你可以在 initialState 表格选项中指定 columnOrder 状态。

jsx
const table = useReactTable({
  //...
  initialState: {
    columnOrder: ['columnId1', 'columnId2', 'columnId3'],
  }
  //...
});
const table = useReactTable({
  //...
  initialState: {
    columnOrder: ['columnId1', 'columnId2', 'columnId3'],
  }
  //...
});

注意: 如果你使用 state 表格选项也指定了 columnOrder 状态,则 initialState 将不起作用。仅在 initialStatestate 中指定特定状态,而不是两者都指定。

管理列顺序状态

如果你需要动态更改列顺序,或在表格初始化后设置列顺序,你可以像管理任何其他表格状态一样管理 columnOrder 状态。

jsx
const [columnOrder, setColumnOrder] = useState<string[]>(['columnId1', 'columnId2', 'columnId3']); //optionally initialize the column order
//...
const table = useReactTable({
  //...
  state: {
    columnOrder,
    //...
  }
  onColumnOrderChange: setColumnOrder,
  //...
});
const [columnOrder, setColumnOrder] = useState<string[]>(['columnId1', 'columnId2', 'columnId3']); //optionally initialize the column order
//...
const table = useReactTable({
  //...
  state: {
    columnOrder,
    //...
  }
  onColumnOrderChange: setColumnOrder,
  //...
});

重新排序各列

如果表格具有允许用户重新排序各列的 UI,你可以像这样设置逻辑

tsx
const [columnOrder, setColumnOrder] = useState<string[]>(columns.map(c => c.id));

//depending on your dnd solution of choice, you may or may not need state like this
const [movingColumnId, setMovingColumnId] = useState<string | null>(null);
const [targetColumnId, setTargetColumnId] = useState<string | null>(null);

//util function to splice and reorder the columnOrder array
const reorderColumn = <TData extends RowData>(
  movingColumnId: Column<TData>,
  targetColumnId: Column<TData>,
): string[] => {
  const newColumnOrder = [...columnOrder];
  newColumnOrder.splice(
    newColumnOrder.indexOf(targetColumnId),
    0,
    newColumnOrder.splice(newColumnOrder.indexOf(movingColumnId), 1)[0],
  );
  setColumnOrder(newColumnOrder);
};

const handleDragEnd = (e: DragEvent) => {
  if(!movingColumnId || !targetColumnId) return;
  setColumnOrder(reorderColumn(movingColumnId, targetColumnId));
};

//use your dnd solution of choice
const [columnOrder, setColumnOrder] = useState<string[]>(columns.map(c => c.id));

//depending on your dnd solution of choice, you may or may not need state like this
const [movingColumnId, setMovingColumnId] = useState<string | null>(null);
const [targetColumnId, setTargetColumnId] = useState<string | null>(null);

//util function to splice and reorder the columnOrder array
const reorderColumn = <TData extends RowData>(
  movingColumnId: Column<TData>,
  targetColumnId: Column<TData>,
): string[] => {
  const newColumnOrder = [...columnOrder];
  newColumnOrder.splice(
    newColumnOrder.indexOf(targetColumnId),
    0,
    newColumnOrder.splice(newColumnOrder.indexOf(movingColumnId), 1)[0],
  );
  setColumnOrder(newColumnOrder);
};

const handleDragEnd = (e: DragEvent) => {
  if(!movingColumnId || !targetColumnId) return;
  setColumnOrder(reorderColumn(movingColumnId, targetColumnId));
};

//use your dnd solution of choice

拖放列重新排序建议 (React)

毫无疑问,有很多方法可以与 TanStack Table 一起实现拖放功能。这里有一些建议,以避免你遇到麻烦

  1. 如果你正在使用 React 18 或更高版本,请不要尝试使用 "react-dnd"。React DnD 在其时代是一个重要的库,但现在更新频率不高,并且与 React 18 不兼容,尤其是在 React 严格模式下。仍然有可能使其工作,但有更新的替代方案具有更好的兼容性并且维护更积极。React DnD 的 Provider 也可能干扰并与你可能想在你的应用程序中尝试的任何其他 DnD 解决方案冲突。

  2. 使用 "@dnd-kit/core"。DnD Kit 是一个现代、模块化和轻量级的拖放库,它与现代 React 生态系统高度兼容,并且可以很好地与语义化的 <table> 标记一起工作。TanStack 官方的两个 DnD 示例,列拖放行拖放,现在都使用 DnD Kit。

  3. 考虑其他 DnD 库,例如 "react-beautiful-dnd",但请注意它们可能很大的捆绑包大小、维护状态以及与 <table> 标记的兼容性。

  4. 考虑使用原生浏览器事件和状态管理来实现轻量级拖放功能。但是,请注意,如果你不额外努力实现适当的触摸事件,则此方法可能不是移动用户的最佳选择。Material React Table V2 是一个库的示例,该库仅使用浏览器拖放事件(例如 onDragStartonDragEndonDragEnter)且不依赖其他依赖项来实现 TanStack Table。浏览其源代码以了解它是如何完成的。

订阅 Bytes

你每周的 JavaScript 新闻。每周一免费发送给超过 10 万名开发者。

Bytes

无垃圾邮件。随时取消订阅。