想直接看实现?可以参考以下示例
默认情况下,列的顺序是它们在 columns 数组中定义的顺序。但是,您可以使用 columnOrder 状态手动指定列顺序。列固定和分组等其他功能也会影响列顺序。
有 3 种表格功能可以重新排序列,它们的顺序如下:
注意: 如果同时使用列固定功能,columnOrder 状态仅会影响未固定的列。
如果您不提供 columnOrder 状态,TanStack Table 将直接使用 columns 数组中的列顺序。但是,您可以向 columnOrder 状态提供一个包含列 ID 字符串的数组,以指定列的顺序。
如果您只需要指定初始列顺序,可以将 columnOrder 状态直接在 initialState 表格选项中进行设置。
const table = useReactTable({
//...
initialState: {
columnOrder: ['columnId1', 'columnId2', 'columnId3'],
}
//...
});
const table = useReactTable({
//...
initialState: {
columnOrder: ['columnId1', 'columnId2', 'columnId3'],
}
//...
});
注意: 如果您同时使用 state 表格选项来指定 columnOrder 状态,那么 initialState 将不起作用。请仅在 initialState 或 state 中指定特定状态,不要两者都指定。
如果您需要动态更改列顺序,或者在表格初始化后设置列顺序,您可以像管理任何其他表格状态一样管理 columnOrder 状态。
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,您可以这样设置逻辑:
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
毫无疑问,有很多方法可以实现与 TanStack Table 并行的拖放功能。以下是一些建议,以避免给您带来不便:
如果您使用的是 React 18 或更高版本,请不要尝试使用 "react-dnd"。React DnD 在其时代是一个重要的库,但现在它更新不频繁,并且与 React 18 存在不兼容性,尤其是在 React 严格模式下。仍然有可能使其工作,但有更新的替代方案,兼容性更好,维护更活跃。React DnD 的 Provider 也可能干扰和冲突您在应用程序中尝试使用的任何其他 DnD 解决方案。
请使用 "@dnd-kit/core"。DnD Kit 是一个现代、模块化且轻量级的拖放库,与现代 React 生态系统高度兼容,并且与语义化的 <table> 标记配合良好。官方 TanStack DnD 示例 Column DnD 和 Row DnD 现在都使用了 DnD Kit。
可以考虑使用其他 DnD 库,例如 "react-beautiful-dnd",但请注意其可能较大的包体积、维护状态以及与 <table> 标记的兼容性。
可以考虑使用原生的浏览器事件和状态管理来实现轻量级的拖放功能。但是,请注意,如果您不花额外精力实现适当的触摸事件,这种方法可能不适合移动用户。 Material React Table V2 是一个实现 TanStack Table 的库的示例,该库仅使用浏览器拖放事件,如 onDragStart、onDragEnd、onDragEnter,并且没有任何其他依赖项。请浏览其源代码以了解实现方式。
您的每周 JavaScript 资讯。每周一免费发送给超过 10 万开发者。