UNPKG

@tanstack/react-table

Version:

Headless UI for building powerful tables & datagrids for React.

172 lines (132 loc) 4.25 kB
--- name: getting-started description: > Create and render a TanStack React Table v9 table with useTable, tableFeatures, stable data and columns, row/header models, and table.FlexRender. Load for a first React table, headless rendering, or when v8 useReactTable examples are producing the wrong setup. metadata: type: framework library: '@tanstack/react-table' library_version: '9.0.0' framework: react requires: - '@tanstack/table-core#core' - '@tanstack/table-core#table-features' sources: - 'TanStack/table:docs/framework/react/guide/migrating.md' - 'TanStack/table:examples/react/basic-use-table' - 'TanStack/table:packages/react-table/src/index.ts' --- This skill builds on `@tanstack/table-core#core` and `@tanstack/table-core#table-features`. Read them first for the headless model and explicit feature registration. ## Setup ```tsx import { useMemo, useState } from 'react' import { createColumnHelper, tableFeatures, useTable, } from '@tanstack/react-table' type Person = { name: string; age: number } const features = tableFeatures({}) const helper = createColumnHelper<typeof features, Person>() const columns = helper.columns([ helper.accessor('name', { header: 'Name' }), helper.accessor('age', { header: 'Age' }), ]) export function PeopleTable() { const [data] = useState<Person[]>([{ name: 'Ada', age: 36 }]) const table = useTable({ features, columns, data }) return ( <table> <thead> {table.getHeaderGroups().map((group) => ( <tr key={group.id}> {group.headers.map((header) => ( <th key={header.id}> {header.isPlaceholder ? null : ( <table.FlexRender header={header} /> )} </th> ))} </tr> ))} </thead> <tbody> {table.getRowModel().rows.map((row) => ( <tr key={row.id}> {row.getAllCells().map((cell) => ( <td key={cell.id}> <table.FlexRender cell={cell} /> </td> ))} </tr> ))} </tbody> </table> ) } ``` Table produces models and state; React owns the semantic markup, styles, event affordances, and accessibility. ## Core Patterns ### Add only the feature the table uses ```tsx import { createSortedRowModel, rowSortingFeature, tableFeatures, } from '@tanstack/react-table' const sortableFeatures = tableFeatures({ rowSortingFeature, sortedRowModel: createSortedRowModel(), }) ``` Row-model slots belong inside `tableFeatures`, after their prerequisite feature. ### Keep static inputs outside render ```tsx const features = tableFeatures({}) const data: Person[] = [{ name: 'Ada', age: 36 }] ``` Use state, memoization, or query results for changing data; avoid a new fallback array every render. ## Common Mistakes ### HIGH Copying the v8 table constructor Wrong: ```tsx const table = useReactTable({ data, columns, getCoreRowModel: getCoreRowModel(), }) ``` Correct: ```tsx const table = useTable({ data, columns, features }) ``` V9 uses `useTable`; optional row models are registered as feature slots rather than table options. Source: `docs/framework/react/guide/migrating.md` ### HIGH Assuming feature APIs are global Wrong: ```tsx const features = tableFeatures({}) ``` Correct: ```tsx const features = tableFeatures({ rowSortingFeature, sortedRowModel: createSortedRowModel(), }) ``` Sorting state and methods do not exist until the sorting feature is registered. Source: `packages/table-core/src/TableFeatures.ts` ### MEDIUM Recreating fallback data each render Wrong: ```tsx const table = useTable({ features, columns, data: response.data ?? [] }) ``` Correct: ```tsx // module scope const EMPTY_DATA: Person[] = [] const table = useTable({ features, columns, data: response.data ?? EMPTY_DATA }) ``` A fresh fallback invalidates data-dependent models on every render. Source: `docs/framework/react/guide/data.md` ## API Discovery Inspect `node_modules/@tanstack/react-table/dist/index.d.ts` first, then the exported `useTable.d.ts`, `FlexRender.d.ts`, or core feature source. Use installed declarations so names match the consumer's exact v9 version.