tanstack v8 React 表 - 如何使用手动排序在服务器端排序

问题描述 投票:0回答:1

我是 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,
  });
sorting graphql server-side react-table tanstack-table
1个回答
19
投票

要在react-table v8中实现手动排序,您需要按照以下步骤操作:

  1. 使用 useState 钩子初始化排序状态。
const [sorting, setSorting] = useState<SortingState>([]);
  1. 将排序状态和
    setSorting
    函数传递给 useReactTable 的
    state.sorting
    onSortingChange
    属性。
const serverSideTable = useReactTable({
  ...
  state: {
    sorting,
  },
  onSortingChange: setSorting,
  ...
});
  1. 通过将
    manualSorting
    属性设置为 true 来启用手动排序。
const serverSideTable = useReactTable({
  ...
  manualSorting: true,
  ...
});
  1. 当用户单击列标题对数据进行排序时,react-table 将调用
    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 上的数据进行排序服务器端。

© www.soinside.com 2019 - 2024. All rights reserved.