TanStack React Table V8结合Apollo GraphQL实现服务端排序指导
TanStack React Table V8 + Apollo GraphQL 服务端排序实现步骤
你已经开启了manualSorting: true,接下来需要把表格的排序状态同步到Apollo查询,再把后端返回的排序后数据回传给表格,具体步骤如下:
1. 明确sorting状态格式
sorting是SortingState类型的数组,每个元素包含列的id(对应你定义的列accessorKey)和desc(是否降序),比如:
// 示例sorting状态 [{ id: 'userName', desc: false }] // 表示按userName升序排序
2. 把sorting转成GraphQL可识别的参数
后端GraphQL接口通常需要特定格式的排序参数(比如[{ field: 'name', order: 'ASC' }]),你代码里的formatLoadSorts应该就是干这个的,如果这个工具函数不符合后端要求,自己写个转换函数:
const formatSortToGraphQL = (sorting: SortingState) => { return sorting.map(item => ({ field: item.id, // 如果列id和后端字段名不一致,这里要映射成后端字段 order: item.desc ? 'DESC' : 'ASC' })); };
3. 在Apollo查询中传入排序+分页参数
用useQuery发起请求时,把sorting转换后的参数和分页参数一起传给后端:
// 假设你的GraphQL查询是GET_TABLE_DATA const { data: serverData, loading } = useQuery(GET_TABLE_DATA, { variables: { page: pagination.pageIndex + 1, // 注意后端分页是否从1开始计数 pageSize: pagination.pageSize, sortBy: formatLoadSorts(sorting) || formatSortToGraphQL(sorting) }, skip: !hasVar // 按你的业务逻辑决定是否跳过查询 });
4. 更新表格数据和总页数
当Apollo返回数据后,把后端的列表数据赋值给表格的data,同时用总条数计算并更新controlledPageCount:
// 先声明data状态变量,替代原来的直接传入的data const [data, setData] = useState<YourRowType[]>([]); useEffect(() => { if (serverData) { // 假设后端返回的数据存在serverData.list里,总条数在serverData.total setData(serverData.list); setControlledPageCount(Math.ceil(serverData.total / pagination.pageSize)); } }, [serverData, pagination.pageSize, setControlledPageCount]);
5. 列配置补充(可选)
如果你的列accessorKey和后端字段名不一致,需要在列定义里指定sortingField,确保排序参数能正确映射到后端字段:
const columns = [ { accessorKey: 'userName', // 表格里用的列id header: '用户名', sortingField: 'name' // 后端GraphQL对应的字段名 }, // 其他列... ];
整合后的完整代码片段
import { useState, useEffect } from 'react'; import { useReactTable, SortingState, PaginationState, getCoreRowModel } from '@tanstack/react-table'; import { useQuery } from '@apollo/client'; import { GET_TABLE_DATA } from './your-queries'; // 导入你的GraphQL查询 // 定义行数据类型 type YourRowType = { userName: string; // 其他字段... }; const YourTableComponent = ({ reactiveVar }) => { const [data, setData] = useState<YourRowType[]>([]); const [sorting, setSorting] = useState<SortingState>([]); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, pageSize: 10, }); const hasVar = Boolean(reactiveVar); const selectedRowId = useReactiveVar( reactiveVar ?? makeVar<SelectedID>(null) ); const { controlledPageCount, setControlledPageCount, formatLoadSorts } = useLoadTableUtils(); // Apollo查询 const { data: serverData } = useQuery(GET_TABLE_DATA, { variables: { page: pagination.pageIndex + 1, pageSize: pagination.pageSize, sortBy: formatLoadSorts(sorting) }, skip: !hasVar }); // 更新表格数据和总页数 useEffect(() => { if (serverData) { setData(serverData.list); setControlledPageCount(Math.ceil(serverData.total / pagination.pageSize)); } }, [serverData, pagination.pageSize, setControlledPageCount]); 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, }); // 渲染表格的逻辑... };
注意点
- 确保后端GraphQL接口支持接收
sortBy参数,并能正确返回排序后的结果 - 当用户点击表头排序时,
onSortingChange会更新sorting状态,Apollo会自动重新发起查询(因为variables依赖了sorting) - 如果需要多列排序,要确认后端支持多字段排序,转换函数也要对应处理多列的情况
内容的提问来源于stack exchange,提问作者devmike9113
相关产品推荐
相关产品推荐

