UNPKG

@tanstack/react-table

Version:

Headless UI for building powerful tables & datagrids for React.

187 lines (145 loc) 4.44 kB
--- name: with-tanstack-query description: > Compose React Table v9 with TanStack Query for server filtering, sorting, pagination, and infinite data. Load for query-key table state, manual* processing boundaries, server rowCount, keepPreviousData, or avoiding duplicated query-result state. metadata: type: composition library: '@tanstack/react-table' library_version: '9.0.0' framework: react requires: - '@tanstack/table-core#client-vs-server' - getting-started - table-state sources: - 'TanStack/table:examples/react/with-tanstack-query' - 'TanStack/table:examples/react/virtualized-infinite-scrolling' - 'TanStack/table:docs/framework/react/guide/pagination.md' --- This skill builds on `@tanstack/table-core#client-vs-server`, `getting-started`, and `table-state`. Query owns fetching/cache; Table owns grid state and receives rows already processed by every manual server stage. ## Setup ```tsx import { keepPreviousData, useQuery } from '@tanstack/react-query' import { useCreateAtom, useSelector } from '@tanstack/react-store' import { rowPaginationFeature, tableFeatures, useTable, } from '@tanstack/react-table' import type { PaginationState } from '@tanstack/react-table' const features = tableFeatures({ rowPaginationFeature }) const emptyRows: Array<{ id: string }> = [] function ServerTable() { const paginationAtom = useCreateAtom<PaginationState>({ pageIndex: 0, pageSize: 20, }) const pagination = useSelector(paginationAtom, (value) => value) const result = useQuery({ queryKey: ['people', pagination], queryFn: async () => fetch( `/api/people?page=${pagination.pageIndex}&size=${pagination.pageSize}`, ).then( (r) => r.json() as Promise<{ rows: Array<{ id: string }> rowCount: number }>, ), placeholderData: keepPreviousData, }) return useTable({ features, columns, data: result.data?.rows ?? emptyRows, rowCount: result.data?.rowCount, atoms: { pagination: paginationAtom }, manualPagination: true, }) } ``` ## Core Patterns ### Put every server-owned slice in the key ```tsx const result = useQuery({ queryKey: ['people', pagination, sorting, columnFilters], queryFn: () => fetchPeople({ pagination, sorting, columnFilters }), }) ``` ### Feed the query result directly to Table ```tsx const table = useTable({ features, columns, data: result.data?.rows ?? emptyRows, }) ``` ## Common Mistakes ### HIGH Duplicating query rows into state Wrong: ```tsx useEffect(() => setRows(result.data?.rows ?? []), [result.data]) const table = useTable({ features, columns, data: rows }) ``` Correct: ```tsx const table = useTable({ features, columns, data: result.data?.rows ?? emptyRows, }) ``` The second state layer can lag behind the query cache and creates an extra synchronization path. Source: `examples/react/with-tanstack-query` ### HIGH Omitting state from the query key Wrong: ```tsx useQuery({ queryKey: ['people'], queryFn: () => fetchPeople({ pagination }) }) ``` Correct: ```tsx useQuery({ queryKey: ['people', pagination], queryFn: () => fetchPeople({ pagination }), }) ``` Query otherwise reuses cache entries for different server requests. Source: `examples/react/with-tanstack-query` ### HIGH Expecting manual mode to fetch Wrong: ```tsx useTable({ features, columns, data, manualPagination: true }) ``` Correct: ```tsx useTable({ features, columns, data: result.data?.rows ?? emptyRows, rowCount: result.data?.rowCount, manualPagination: true, }) ``` `manualPagination` only bypasses client pagination; the application must fetch a processed page and provide its total count. Source: `docs/framework/react/guide/pagination.md` ### MEDIUM Flashing an empty page during fetch Wrong: ```tsx useQuery({ queryKey: ['people', pagination], queryFn: () => fetchPeople({ pagination }), }) ``` Correct: ```tsx useQuery({ queryKey: ['people', pagination], queryFn: () => fetchPeople({ pagination }), placeholderData: keepPreviousData, }) ``` Preserve the previous page intentionally when an empty loading transition is undesirable. Source: `examples/react/with-tanstack-query` ## API Discovery Inspect `node_modules/@tanstack/react-table/dist/index.d.ts` and the relevant core feature source; inspect the installed `@tanstack/react-query` source for current query option types.