想跳过实现步骤?查看这些示例
TanStack Table 为您可能遇到的几乎任何排序用例提供了解决方案。本指南将引导您了解各种选项,您可以使用这些选项来自定义内置的客户端排序功能,以及如何选择退出客户端排序,转而使用手动服务端排序。
排序状态被定义为一个对象数组,具有以下形状
type ColumnSort = {
id: string
desc: boolean
}
type SortingState = ColumnSort[]
type ColumnSort = {
id: string
desc: boolean
}
type SortingState = ColumnSort[]
由于排序状态是一个数组,因此可以一次按多列排序。请阅读下文以了解有关多列排序自定义的更多信息。
您可以像访问任何其他状态一样,直接从表格实例访问排序状态,使用 table.getState() API。
const table = useReactTable({
columns,
data,
//...
})
console.log(table.getState().sorting) // access the sorting state from the table instance
const table = useReactTable({
columns,
data,
//...
})
console.log(table.getState().sorting) // access the sorting state from the table instance
但是,如果您需要在表格初始化之前访问排序状态,您可以像下面这样“控制”排序状态。
如果您需要轻松访问排序状态,您可以使用 state.sorting 和 onSortingChange 表格选项在您自己的状态管理中控制/管理排序状态。
const [sorting, setSorting] = useState<SortingState>([]) // can set initial sorting state here
//...
// use sorting state to fetch data from your server or something...
//...
const table = useReactTable({
columns,
data,
//...
state: {
sorting,
},
onSortingChange: setSorting,
})
const [sorting, setSorting] = useState<SortingState>([]) // can set initial sorting state here
//...
// use sorting state to fetch data from your server or something...
//...
const table = useReactTable({
columns,
data,
//...
state: {
sorting,
},
onSortingChange: setSorting,
})
如果您不需要在您自己的状态管理或作用域中控制排序状态,但您仍然想要设置初始排序状态,您可以使用 initialState 表格选项代替 state。
const table = useReactTable({
columns,
data,
//...
initialState: {
sorting: [
{
id: 'name',
desc: true, // sort by name in descending order by default
},
],
},
})
const table = useReactTable({
columns,
data,
//...
initialState: {
sorting: [
{
id: 'name',
desc: true, // sort by name in descending order by default
},
],
},
})
注意:不要同时使用 initialState.sorting 和 state.sorting,因为 state.sorting 中的初始化状态将覆盖 initialState.sorting。
您应该使用客户端排序还是服务端排序完全取决于您是否同时使用客户端或服务端分页或筛选。请保持一致,因为将客户端排序与服务端分页或筛选一起使用只会对当前加载的数据进行排序,而不会对整个数据集进行排序。
如果您计划仅在您的后端逻辑中使用您自己的服务端排序,则无需提供排序后的行模型。但是,如果您已经提供了排序行模型,但想要禁用它,您可以使用 manualSorting 表格选项。
const [sorting, setSorting] = useState<SortingState>([])
//...
const table = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
//getSortedRowModel: getSortedRowModel(), //not needed for manual sorting
manualSorting: true, //use pre-sorted row model instead of sorted row model
state: {
sorting,
},
onSortingChange: setSorting,
})
const [sorting, setSorting] = useState<SortingState>([])
//...
const table = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
//getSortedRowModel: getSortedRowModel(), //not needed for manual sorting
manualSorting: true, //use pre-sorted row model instead of sorted row model
state: {
sorting,
},
onSortingChange: setSorting,
})
注意:当 manualSorting 设置为 true 时,表格将假定您提供的数据已排序,并且不会对其应用任何排序。
要实现客户端排序,首先您必须为表格提供一个排序行模型。您可以从 TanStack Table 导入 getSortedRowModel 函数,它将用于将您的行转换为排序后的行。
import { useReactTable } from '@tanstack/react-table'
//...
const table = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(), //provide a sorting row model
})
import { useReactTable } from '@tanstack/react-table'
//...
const table = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(), //provide a sorting row model
})
所有列的默认排序函数是从列的数据类型推断出来的。但是,为特定列定义您想要使用的确切排序函数可能很有用,特别是如果您的任何数据是可为空的或不是标准数据类型。
您可以使用 sortingFn 列选项在每列的基础上确定自定义排序函数。
默认情况下,有 6 个内置排序函数可供选择
您还可以定义自己的自定义排序函数,可以作为 sortingFn 列选项,也可以使用 sortingFns 表格选项作为全局排序函数。
当在 sortingFns 表格选项或 sortingFn 列选项中定义自定义排序函数时,它应该具有以下签名
//optionally use the SortingFn to infer the parameter types
const myCustomSortingFn: SortingFn<TData> = (rowA: Row<TData>, rowB: Row<TData>, columnId: string) => {
return //-1, 0, or 1 - access any row data using rowA.original and rowB.original
}
//optionally use the SortingFn to infer the parameter types
const myCustomSortingFn: SortingFn<TData> = (rowA: Row<TData>, rowB: Row<TData>, columnId: string) => {
return //-1, 0, or 1 - access any row data using rowA.original and rowB.original
}
注意:比较函数不需要考虑列是否按降序或升序排列。行模型将处理该逻辑。sortingFn 函数只需要提供一致的比较。
每个排序函数接收 2 行和一个列 ID,并期望使用列 ID 比较这两行,以升序返回 -1、0 或 1。这是一个速查表
返回 | 升序 |
---|---|
-1 | a < b |
0 | a === b |
1 | a > b |
const columns = [
{
header: () => 'Name',
accessorKey: 'name',
sortingFn: 'alphanumeric', // use built-in sorting function by name
},
{
header: () => 'Age',
accessorKey: 'age',
sortingFn: 'myCustomSortingFn', // use custom global sorting function
},
{
header: () => 'Birthday',
accessorKey: 'birthday',
sortingFn: 'datetime', // recommended for date columns
},
{
header: () => 'Profile',
accessorKey: 'profile',
// use custom sorting function directly
sortingFn: (rowA, rowB, columnId) => {
return rowA.original.someProperty - rowB.original.someProperty
},
}
]
//...
const table = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
sortingFns: { //add a custom sorting function
myCustomSortingFn: (rowA, rowB, columnId) => {
return rowA.original[columnId] > rowB.original[columnId] ? 1 : rowA.original[columnId] < rowB.original[columnId] ? -1 : 0
},
},
})
const columns = [
{
header: () => 'Name',
accessorKey: 'name',
sortingFn: 'alphanumeric', // use built-in sorting function by name
},
{
header: () => 'Age',
accessorKey: 'age',
sortingFn: 'myCustomSortingFn', // use custom global sorting function
},
{
header: () => 'Birthday',
accessorKey: 'birthday',
sortingFn: 'datetime', // recommended for date columns
},
{
header: () => 'Profile',
accessorKey: 'profile',
// use custom sorting function directly
sortingFn: (rowA, rowB, columnId) => {
return rowA.original.someProperty - rowB.original.someProperty
},
}
]
//...
const table = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
sortingFns: { //add a custom sorting function
myCustomSortingFn: (rowA, rowB, columnId) => {
return rowA.original[columnId] > rowB.original[columnId] ? 1 : rowA.original[columnId] < rowB.original[columnId] ? -1 : 0
},
},
})
有很多表格和列选项可供您使用,以进一步自定义排序 UX 和行为。
您可以使用 enableSorting 列选项或表格选项禁用特定列或整个表格的排序。
const columns = [
{
header: () => 'ID',
accessorKey: 'id',
enableSorting: false, // disable sorting for this column
},
{
header: () => 'Name',
accessorKey: 'name',
},
//...
]
//...
const table = useReactTable({
columns,
data,
enableSorting: false, // disable sorting for the entire table
})
const columns = [
{
header: () => 'ID',
accessorKey: 'id',
enableSorting: false, // disable sorting for this column
},
{
header: () => 'Name',
accessorKey: 'name',
},
//...
]
//...
const table = useReactTable({
columns,
data,
enableSorting: false, // disable sorting for the entire table
})
默认情况下,使用 toggleSorting API 循环列排序时,字符串列的第一个排序方向是升序,数字列的第一个排序方向是降序。您可以使用 sortDescFirst 列选项或表格选项更改此行为。
const columns = [
{
header: () => 'Name',
accessorKey: 'name',
sortDescFirst: true, //sort by name in descending order first (default is ascending for string columns)
},
{
header: () => 'Age',
accessorKey: 'age',
sortDescFirst: false, //sort by age in ascending order first (default is descending for number columns)
},
//...
]
//...
const table = useReactTable({
columns,
data,
sortDescFirst: true, //sort by all columns in descending order first (default is ascending for string columns and descending for number columns)
})
const columns = [
{
header: () => 'Name',
accessorKey: 'name',
sortDescFirst: true, //sort by name in descending order first (default is ascending for string columns)
},
{
header: () => 'Age',
accessorKey: 'age',
sortDescFirst: false, //sort by age in ascending order first (default is descending for number columns)
},
//...
]
//...
const table = useReactTable({
columns,
data,
sortDescFirst: true, //sort by all columns in descending order first (default is ascending for string columns and descending for number columns)
})
注意:您可能需要在任何具有可为空值的列上显式设置 sortDescFirst 列选项。如果列包含可为空的值,则表格可能无法正确确定列是数字还是字符串。
反转排序与更改默认排序方向不同。如果列的 invertSorting 列选项为 true,则“desc/asc”排序状态仍将像往常一样循环,但行的实际排序将被反转。这对于具有反向最佳/最差比例的值很有用,其中较低的数字更好,例如排名(第 1 名、第 2 名、第 3 名)或类似高尔夫的计分。
const columns = [
{
header: () => 'Rank',
accessorKey: 'rank',
invertSorting: true, // invert the sorting for this column. 1st -> 2nd -> 3rd -> ... even if "desc" sorting is applied
},
//...
]
const columns = [
{
header: () => 'Rank',
accessorKey: 'rank',
invertSorting: true, // invert the sorting for this column. 1st -> 2nd -> 3rd -> ... even if "desc" sorting is applied
},
//...
]
任何未定义的值都将根据 sortUndefined 列选项或表格选项排序到列表的开头或结尾。您可以为您的特定用例自定义此行为。
如果未指定,sortUndefined 的默认值为 1,未定义的值将以较低的优先级排序(降序),如果升序,未定义的值将出现在列表的末尾。
注意:'first' 和 'last' 选项是 v8.16.0 中的新功能
const columns = [
{
header: () => 'Rank',
accessorKey: 'rank',
sortUndefined: -1, // 'first' | 'last' | 1 | -1 | false
},
]
const columns = [
{
header: () => 'Rank',
accessorKey: 'rank',
sortUndefined: -1, // 'first' | 'last' | 1 | -1 | false
},
]
默认情况下,在循环列的排序状态时,移除排序的功能已启用。您可以使用 enableSortingRemoval 表格选项禁用此行为。如果您想确保始终至少对一列进行排序,则此行为很有用。
当使用 getToggleSortingHandler 或 toggleSorting API 时,默认行为是像这样循环排序状态
'none' -> 'desc' -> 'asc' -> 'none' -> 'desc' -> 'asc' -> ...
如果您禁用移除排序,则行为将如下所示
'none' -> 'desc' -> 'asc' -> 'desc' -> 'asc' -> ...
一旦列被排序且 enableSortingRemoval 为 false,则在该列上切换排序将永远不会移除排序。但是,如果用户按另一列排序,并且它不是多列排序事件,则排序将从前一列中移除,并仅应用于新列。
如果您想确保始终至少对一列进行排序,请将 enableSortingRemoval 设置为 false。
const table = useReactTable({
columns,
data,
enableSortingRemoval: false, // disable the ability to remove sorting on columns (always none -> asc -> desc -> asc)
})
const table = useReactTable({
columns,
data,
enableSortingRemoval: false, // disable the ability to remove sorting on columns (always none -> asc -> desc -> asc)
})
如果使用 column.getToggleSortingHandler API,则默认启用一次按多列排序。如果用户在单击列标题时按住 Shift 键,则表格将按该列以及已排序的列进行排序。如果您使用 column.toggleSorting API,则必须手动传入是否使用多列排序。(column.toggleSorting(desc, multi))。
您可以使用 enableMultiSort 列选项或表格选项禁用特定列或整个表格的多列排序。禁用特定列的多列排序会将所有现有排序替换为新列的排序。
const columns = [
{
header: () => 'Created At',
accessorKey: 'createdAt',
enableMultiSort: false, // always sort by just this column if sorting by this column
},
//...
]
//...
const table = useReactTable({
columns,
data,
enableMultiSort: false, // disable multi-sorting for the entire table
})
const columns = [
{
header: () => 'Created At',
accessorKey: 'createdAt',
enableMultiSort: false, // always sort by just this column if sorting by this column
},
//...
]
//...
const table = useReactTable({
columns,
data,
enableMultiSort: false, // disable multi-sorting for the entire table
})
默认情况下,Shift 键用于触发多列排序。您可以使用 isMultiSortEvent 表格选项更改此行为。您甚至可以指定所有排序事件都应通过从自定义函数返回 true 来触发多列排序。
const table = useReactTable({
columns,
data,
isMultiSortEvent: (e) => true, // normal click triggers multi-sorting
//or
isMultiSortEvent: (e) => e.ctrlKey || e.shiftKey, // also use the `Ctrl` key to trigger multi-sorting
})
const table = useReactTable({
columns,
data,
isMultiSortEvent: (e) => true, // normal click triggers multi-sorting
//or
isMultiSortEvent: (e) => e.ctrlKey || e.shiftKey, // also use the `Ctrl` key to trigger multi-sorting
})
默认情况下,一次可以排序的列数没有限制。您可以使用 maxMultiSortColCount 表格选项设置限制。
const table = useReactTable({
columns,
data,
maxMultiSortColCount: 3, // only allow 3 columns to be sorted at once
})
const table = useReactTable({
columns,
data,
maxMultiSortColCount: 3, // only allow 3 columns to be sorted at once
})
默认情况下,移除多列排序的功能已启用。您可以使用 enableMultiRemove 表格选项禁用此行为。
const table = useReactTable({
columns,
data,
enableMultiRemove: false, // disable the ability to remove multi-sorts
})
const table = useReactTable({
columns,
data,
enableMultiRemove: false, // disable the ability to remove multi-sorts
})
有很多与排序相关的 API,您可以用来连接到您的 UI 或其他逻辑。以下是所有排序 API 及其一些用例的列表。
table.setSorting - 直接设置排序状态。
table.resetSorting - 将排序状态重置为初始状态或清除它。
column.getCanSort - 用于启用/禁用列的排序 UI。
column.getIsSorted - 用于显示列的视觉排序指示器。
column.getToggleSortingHandler - 用于连接列的排序 UI。添加到排序箭头(图标按钮)、菜单项或仅添加到整个列标题单元格。此处理程序将使用正确的参数调用 column.toggleSorting。
column.toggleSorting - 用于连接列的排序 UI。如果使用它而不是 column.getToggleSortingHandler,您必须手动传入是否使用多列排序。(column.toggleSorting(desc, multi))
column.clearSorting - 用于特定列的“清除排序”按钮或菜单项。
column.getNextSortingOrder - 用于显示列接下来将按哪个方向排序。(在工具提示/菜单项/aria-label 中显示 asc/desc/clear 或其他内容)
column.getFirstSortDir - 用于显示列将首先按哪个方向排序。(在工具提示/菜单项/aria-label 中显示 asc/desc 或其他内容)
column.getAutoSortDir - 确定列的第一个排序方向是升序还是降序。
column.getAutoSortingFn - 在内部使用,以查找列的默认排序函数(如果未指定)。
column.getSortingFn - 返回用于列的确切排序函数。
column.getCanMultiSort - 用于启用/禁用列的多列排序 UI。
column.getSortIndex - 用于在多列排序场景中显示列的排序顺序的徽章或指示器。即,它是要排序的第一列、第二列、第三列等。
您的每周 JavaScript 新闻。每周一免费发送给超过 10 万名开发者。