我是 tanstack React Table V8 的新手……在某些方面似乎与 V7 有很大不同,希望得到一些建议。
我需要使用 apollo graphql 对服务器端进行排序。
通过阅读文档,我知道您需要使用“manualSorting”道具...只是不清楚从那里到底要做什么
const [sorting, setSorting] = useState<SortingState>([]);
const hasVar = Boolean(reactiveVar);
const selectedRowId = useReactiveVar(
reactiveVar ?? makeVar<SelectedID>(null)
);
const { controlledPageCount, setControlledPageCount, formatLoadSorts } =
useLoadTableUtils();
const serverSideTable = useReactTable({
data,
columns,
pageCount: controlledPageCount,
state: {
sorting,
pagination,
},
onPaginationChange: setPagination,
manualPagination: true,
onSortingChange: setSorting,
manualSorting: true,
debugTable: true,
getCoreRowModel: getCoreRowModel(),
enableSorting: true,
sortingFns,
});
要在react-table v8中实现手动排序,您需要按照以下步骤操作:
const [sorting, setSorting] = useState<SortingState>([]);
setSorting
函数传递给 useReactTable 的 state.sorting
和 onSortingChange
属性。const serverSideTable = useReactTable({
...
state: {
sorting,
},
onSortingChange: setSorting,
...
});
manualSorting
属性设置为 true 来启用手动排序。const serverSideTable = useReactTable({
...
manualSorting: true,
...
});
setSorting
函数并更新排序状态。然后,您可以使用此状态向服务器发送请求以检索排序后的数据。正如我所看到的,在你的例子中你已经做到了。此外,一切都非常简单,您可以根据需要修改排序并将请求发送到服务器。
例如,我使用 RTK 查询来获取数据并在后端进行嵌套分页。这是我的简单实现示例:
// UsersTable.tsx
import type { SortingState } from '@tanstack/react-table';
import React from 'react';
import { ReactTable } from '@/components/ui/ReactTable';
import { useGetUsersQuery } from '@/store/user/user.api';
import { columns } from './columns';
export const UsersTable = () => {
const [sorting, setSorting] = React.useState<SortingState>([]);
const { data, isLoading, isFetching } = useGetUsersQuery({
sortBy: sorting.map((s) => `${s.id}:${s.desc ? 'DESC' : 'ASC'}`).join(','),
});
return (
<ReactTable
data={data?.data || []}
columns={columns}
isLoading={isLoading || isFetching}
sorting={sorting}
setSorting={setSorting}
/>
);
};
// ReactTable.tsx
import type {
ColumnDef,
OnChangeFn,
SortingState,
} from '@tanstack/react-table';
import {
flexRender,
getCoreRowModel,
useReactTable,
} from '@tanstack/react-table';
import { ArrowDown, ArrowUp } from 'phosphor-react';
import React from 'react';
import { Table, TableHead, TableHeadCell } from '../Table';
import { TableBody } from '../Table/TableBody';
import { TableCell } from '../Table/TableCell';
import { TableRow } from '../Table/TableRow';
export interface TableProps<TData> {
data: TData[];
columns: ColumnDef<TData>[];
isLoading?: boolean;
sorting?: SortingState;
setSorting?: OnChangeFn<SortingState>;
}
export const ReactTable = <TData extends object>({
data,
columns,
isLoading,
sorting,
setSorting,
}: TableProps<TData>) => {
const memoizedData = React.useMemo(() => data, [data]);
const memoizedColumns = React.useMemo(() => columns, [columns]);
const table = useReactTable({
data: memoizedData,
columns: memoizedColumns,
state: {
sorting,
},
manualSorting: true,
onSortingChange: setSorting,
getCoreRowModel: getCoreRowModel(),
});
const isNoDataFound =
!isLoading && (!memoizedData || memoizedData.length === 0);
return (
<div className="relative overflow-hidden border bg-white dark:border-gray-700 dark:bg-gray-900 sm:rounded-xl">
{!isNoDataFound &&
(isLoading ? (
<div className="flex h-full w-full items-center justify-center p-8">
Loading...
</div>
) : (
<Table>
<TableHead>
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHeadCell key={header.id} colSpan={header.colSpan}>
{header.isPlaceholder ? null : (
<div
{...{
className: header.column.getCanSort()
? 'select-none cursor-pointer flex items-center gap-1'
: '',
onClick: header.column.getToggleSortingHandler(),
}}
>
{flexRender(
header.column.columnDef.header,
header.getContext(),
)}
{{
asc: <ArrowDown className="h-4 w-4" />,
desc: <ArrowUp className="h-4 w-4" />,
}[header.column.getIsSorted() as string] ?? null}
</div>
)}
</TableHeadCell>
);
})}
</tr>
))}
</TableHead>
<TableBody>
{table.getRowModel().rows.map((row) => (
<TableRow key={row.id}>
{row.getVisibleCells().map((cell) => {
return (
<TableCell key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext(),
)}
</TableCell>
);
})}
</TableRow>
))}
</TableBody>
</Table>
))}
</div>
);
};
我还没有使用过 GraphQL Apollo,所以我不能确切地说它是如何实现的,但很可能您需要将排序状态作为变量传递到 GraphQL 查询中,并使用这些变量对 GraphQL 上的数据进行排序服务器端。