tanstack-table について
TanStack Tableは、データを扱う React 画面向けのモジュール型テーブルライブラリです。このスキルでは、型付きの列定義、行モデル、テーブル状態の制御方法を説明します。
主な機能
- 01モジュール型の行モデル処理
- 02型安全な列定義
- 03ソートとフィルターのパターン
- 04ページネーションと選択状態
- 05列の表示・サイズ調整の指針
活用シーン
- 01ソート可能なデータテーブルの構築
- 02列フィルターと全体検索の追加
- 03ページネーションと行選択の制御
- 04列の動的な表示や幅変更
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ marcioaltoe/ skills --skill tanstack-tableインストール後、Claude Code で/tanstack-tableを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlrules/col-column-defs.mdexp-expanding.mdfilt-column-filtering.mdfilt-global-filtering.mdpag-pagination.mdrm-row-models.mdsel-row-selection.mdsize-column-sizing.mdsort-sorting.mdtable-setup.mdvis-column-visibility.md詳細
TanStack Table
バージョン: @tanstack/react-table@latest 必要条件: React 16.8 以降、TypeScript を推奨
クイックセットアップ
npm install @tanstack/react-table
import {
useReactTable,
getCoreRowModel,
flexRender,
createColumnHelper,
} from '@tanstack/react-table'
type User = {
name: string
age: number
status: string
}
const columnHelper = createColumnHelper<User>()
const columns = [
columnHelper.accessor('name', { header: 'Name' }),
columnHelper.accessor('age', { header: 'Age' }),
columnHelper.accessor('status', { header: 'Status' }),
columnHelper.display({
id: 'actions',
cell: (props) => <button onClick={() => edit(props.row.original)}>Edit</button>,
}),
]
function App() {
const [data] = useState<User[]>([]) // must be stable reference
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
})
return (
<table>
<thead>
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th key={header.id}>
{flexRender(header.column.columnDef.header, header.getContext())}
</th>
))}
</tr>
))}
</thead>
<tbody>
{table.getRowModel().rows.map((row) => (
<tr key={row.id}>
{row.getVisibleCells().map((cell) => (
<td key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
))}
</tr>
))}
</tbody>
</table>
)
}
行モデル(必要なものだけをインポート)
TanStack Table はモジュール式です。実際に使用する行モデルだけをインポートしてください。
import {
getCoreRowModel, // required
getSortedRowModel, // client-side sorting
getFilteredRowModel, // client-side filtering
getPaginationRowModel,// client-side pagination
getExpandedRowModel, // expanding/sub-rows
getGroupedRowModel, // grouping + aggregation
getFacetedRowModel, // faceted values
getFacetedUniqueValues,
getFacetedMinMaxValues,
} from '@tanstack/react-table'
パイプラインの順序:コア -> フィルタリング済み -> グループ化済み -> ソート済み -> 展開済み -> ページ分割済み -> レンダリング済み
ルールのカテゴリ
| 優先度 | カテゴリ | ルールファイル | 影響 |
|---|---|---|---|
| CRITICAL | テーブルのセットアップ | rules/table-setup.md | 正しいテーブルの作成、安定したデータ参照 |
| CRITICAL | カラム定義 | rules/col-column-defs.md | データモデル、レンダリング、型安全性 |
| CRITICAL | 行モデル | rules/rm-row-models.md | モジュール式のインポート、パイプラインの順序 |
| HIGH | ソート | rules/sort-sorting.md | クライアント/サーバーでのソート、カスタムソート関数 |
| HIGH | カラムフィルタリング | rules/filt-column-filtering.md | カラムごとのフィルター、カスタムフィルター関数 |
| HIGH | グローバルフィルタリング | rules/filt-global-filtering.md | テーブル全体の検索、グローバルフィルター関数 |
| HIGH | ページネーション | rules/pag-pagination.md | クライアント/サーバーでのページネーション、ページ状態 |
| MEDIUM | 行選択 | rules/sel-row-selection.md | チェックボックス/ラジオボタンによる選択、選択状態 |
| MEDIUM | カラムの表示設定 | rules/vis-column-visibility.md | カラムの動的な表示/非表示 |
| MEDIUM | カラムサイズ設定 | rules/size-column-sizing.md | 幅、サイズ変更、パフォーマンス |
| LOW | 展開 | rules/exp-expanding.md | サブ行、詳細パネル、階層データ |
重要なルール
必ず行うこと
- 安定した
data参照を使用する — 無限の再レンダリングを防ぐため、useState、useMemoを使用するか、コンポーネントの外で定義してください createColumnHelper<TData>()を使用する — カラム定義の型安全性を最大限に高めるために使用します- 必要な行モデルだけをインポートする — クライアント側でソートしない場合は、
getSortedRowModelをインポートしないでください flexRenderを使用する — カラム定義からヘッダー/セル/フッターのテンプレートをレンダリングするために使用しますgetVisibleCells()を使用する — カラムの表示設定を反映するため、getAllCells()ではなくこちらを使用しますgetRowModel()を使用する — フィルタリング、ソート、ページネーションなど、すべての機能を適用した最終的な行モデルですstateとon*Changeで状態を制御する — ソート、フィルタリング、ページネーション、選択などに使用します
絶対に行わないこと
dataをインラインで定義する —useReactTable({ data: fetchData() })は無限の再レンダリングを引き起こします- レンダー中に
columnsを定義する — カラム配列は安定している必要があります(コンポーネントの外で定義するか、useMemoを使用してください) - レンダリングに
getAllCells()を使用する — カラムの表示設定が無視されます。getVisibleCells()を使用してください - 同じ機能に
initialStateとstateを併用する —stateがinitialStateを上書きします manual*オプションとクライアント側の行モデルを併用する —manualSorting: trueの場合は、getSortedRowModelをインポートしないでくださいgetRowIdを忘れない — 指定しない場合、行 ID はインデックスが既定値となり、再取得後に選択状態が崩れます
主なパターン
// Controlled sorting state
const [sorting, setSorting] = useState<SortingState>([])
const table = useReactTable({
data, columns,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
state: { sorting },
onSortingChange: setSorting,
})
// Header click handler
<th onClick={header.column.getToggleSortingHandler()}>
{flexRender(header.column.columnDef.header, header.getContext())}
{{ asc: ' 🔼', desc: ' 🔽' }[header.column.getIsSorted() as string] ?? ''}
</th>
// Server-side pagination
const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 })
const table = useReactTable({
data, columns,
getCoreRowModel: getCoreRowModel(),
manualPagination: true,
rowCount: serverData.totalRows,
state: { pagination },
onPaginationChange: setPagination,
})
// Row selection with checkbox column
columnHelper.display({
id: 'select',
header: ({ table }) => (
<input type="checkbox" checked={table.getIsAllRowsSelected()}
onChange={table.getToggleAllRowsSelectedHandler()} />
),
cell: ({ row }) => (
<input type="checkbox" checked={row.getIsSelected()}
disabled={!row.getCanSelect()}
onChange={row.getToggleSelectedHandler()} />
),
})
// Column filtering
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
const table = useReactTable({
data, columns,
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
state: { columnFilters },
onColumnFiltersChange: setColumnFilters,
})
// Filter input
<input value={column.getFilterValue() ?? ''} onChange={e => column.setFilterValue(e.target.value)} />
// Stable row IDs for selection across re-fetches
const table = useReactTable({
data, columns,
getRowId: (row) => row.uuid,
getCoreRowModel: getCoreRowModel(),
})
コメント
Markdown 対応