mcpField
T
tanstack-table

tanstack-table

github.com/marcioaltoe開発062 回インストール1 日前に更新
リポジトリ

tanstack-table について

TanStack Tableは、データを扱う React 画面向けのモジュール型テーブルライブラリです。このスキルでは、型付きの列定義、行モデル、テーブル状態の制御方法を説明します。

主な機能

  1. 01モジュール型の行モデル処理
  2. 02型安全な列定義
  3. 03ソートとフィルターのパターン
  4. 04ページネーションと選択状態
  5. 05列の表示・サイズ調整の指針

活用シーン

  1. 01ソート可能なデータテーブルの構築
  2. 02列フィルターと全体検索の追加
  3. 03ページネーションと行選択の制御
  4. 04列の動的な表示や幅変更

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/marcioaltoe/skills --skill tanstack-table

インストール後、Claude Code で/tanstack-tableを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

agents/
openai.yaml
rules/
col-column-defs.md
exp-expanding.md
filt-column-filtering.md
filt-global-filtering.md
pag-pagination.md
rm-row-models.md
sel-row-selection.md
size-column-sizing.md
sort-sorting.md
table-setup.md
vis-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(),
})

コメント