mcpField
R
react-tanstack-senior

react-tanstack-senior

github.com/modra40開発5157 回インストール33 週間前に更新
リポジトリ

react-tanstack-senior について

TanStack ライブラリを使った React アプリの開発と保守を支援するスキルです。プロジェクト設定の指針、エコシステムの資料、コード規約、デバッグやレビューのチェック項目を提供します。

主な機能

  1. 01状態とプロジェクト種別に応じたツール選択
  2. 02SPA またはフルスタック構成のセットアップ
  3. 03TanStack ライブラリ資料の参照
  4. 04命名とコンポーネント規約の適用
  5. 05よくある不具合と性能の確認

活用シーン

  1. 01新しい React プロジェクトの構成計画
  2. 02TanStack ライブラリの段階的な導入
  3. 03コンポーネントと TypeScript 規約の確認
  4. 04性能問題や一般的な不具合の調査

インストール

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

$npx skills add https://github.com/modra40/claude-codex-skills-directory --skill react-tanstack-senior

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

同梱ファイル

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

references/
common-pitfalls.md
debugging-guide.md
folder-structure.md
recommended-libraries.md
tanstack-form.md
tanstack-query.md
tanstack-router.md
tanstack-start.md
tanstack-table.md

詳細

React + TanStack シニア開発者スキル

基本理念

KISS > Clever Code
Readability > Brevity  
Explicit > Implicit
Composition > Inheritance
Colocation > Separation
Type Safety > Any

クイック判断ツリー

状態管理:

  • サーバー状態 → TanStack Query(必須)
  • URL 状態 → TanStack Router の検索パラメーター
  • フォーム状態 → TanStack Form または React Hook Form
  • グローバル UI 状態 → Zustand(Redux ではない)
  • ローカル UI 状態 → useState/useReducer

ルーティング:

  • SPA → TanStack Router
  • フルスタック SSR → TanStack Start
  • 既存の Next.js → Next.js を引き続き使用

プロジェクトセットアップのワークフロー

  1. プロジェクトの種類を判断:

    • SPA/クライアントのみ? → Vite + TanStack Router + Query
    • フルスタック SSR? → TanStack Start(Vinxi ベース)
    • 既存のプロジェクト? → 段階的に導入
  2. プロジェクトを初期化 → folder-structure.md を参照

  3. コア依存関係をセットアップ → recommended-libraries.md を参照

TanStack エコシステムのリファレンス

ライブラリ参照するタイミング
tanstack-query.mdデータ取得、キャッシュ、ミューテーション
tanstack-router.md型安全なルーティング、ローダー、検索パラメーター
tanstack-table.md複雑なテーブル、並べ替え、フィルタリング、ページネーション
tanstack-form.mdフォームの検証、フィールド配列、非同期検証
tanstack-start.mdフルスタック SSR フレームワーク

コード品質基準

命名規則
// Components: PascalCase dengan suffix deskriptif
UserProfileCard.tsx      // ✓
UserCard.tsx             // ✗ terlalu generic
user-profile.tsx         // ✗ wrong case

// Hooks: camelCase dengan prefix 'use'
useUserProfile()         // ✓
useGetUserProfile()      // ✗ redundant 'Get'
getUserProfile()         // ✗ missing 'use'

// Query keys: array dengan hierarchy
['users', 'list', { status }]           // ✓
['usersList']                            // ✗ tidak granular
`users-${status}`                        // ✗ string interpolation

// Files: kebab-case untuk non-components
api-client.ts            // ✓
apiClient.ts             // ✗ 
コンポーネント構成パターン
// 1. Imports (grouped: external → internal → types)
import { useSuspenseQuery } from '@tanstack/react-query'
import { userQueries } from '@/features/users/api'
import type { User } from '@/features/users/types'

// 2. Types (colocated, tidak di file terpisah kecuali shared)
interface UserCardProps {
  userId: string
  onSelect?: (user: User) => void
}

// 3. Component (single responsibility)
export function UserCard({ userId, onSelect }: UserCardProps) {
  // 3a. Queries/mutations first
  const { data: user } = useSuspenseQuery(userQueries.detail(userId))
  
  // 3b. Derived state (useMemo hanya jika expensive)
  const fullName = `${user.firstName} ${user.lastName}`
  
  // 3c. Handlers (useCallback hanya jika passed to memoized children)
  const handleClick = () => onSelect?.(user)
  
  // 3d. Early returns untuk edge cases
  if (!user.isActive) return null
  
  // 3e. JSX (clean, minimal nesting)
  return (
    <article onClick={handleClick} className="user-card">
      <h3>{fullName}</h3>
      <p>{user.email}</p>
    </article>
  )
}

避けるべきアンチパターン

// ❌ NEVER: useEffect untuk data fetching
useEffect(() => {
  fetch('/api/users').then(setUsers)
}, [])

// ✅ ALWAYS: TanStack Query
const { data: users } = useQuery(userQueries.list())

// ❌ NEVER: Prop drilling lebih dari 2 level
<Parent userData={user}>
  <Child userData={user}>
    <GrandChild userData={user} />

// ✅ ALWAYS: Context atau query di level yang butuh
function GrandChild() {
  const { data: user } = useQuery(userQueries.current())
}

// ❌ NEVER: Premature optimization
const value = useMemo(() => a + b, [a, b]) // simple math

// ✅ ALWAYS: Optimize only when measured
const value = a + b // just calculate

// ❌ NEVER: Index as key untuk dynamic lists
{items.map((item, i) => <Item key={i} />)}

// ✅ ALWAYS: Stable unique identifier
{items.map(item => <Item key={item.id} />)}

デバッグガイド

debugging-guide.md では、以下を説明しています:

  • React DevTools によるプロファイリング
  • TanStack Query DevTools
  • メモリーリークの検出
  • パフォーマンスのボトルネックの特定
  • よくあるエラーパターン

よくある落とし穴とバグ

common-pitfalls.md では、以下を説明しています:

  • 古いクロージャによるバグ
  • 競合状態
  • メモリーリークのパターン
  • ハイドレーションの不一致
  • クエリーの無効化に関する間違い

パフォーマンスチェックリスト

□ Bundle size < 200KB gzipped (initial)
□ Largest Contentful Paint < 2.5s
□ No unnecessary re-renders (React DevTools)
□ Images lazy loaded
□ Code splitting per route
□ Query deduplication working
□ No memory leaks (heap snapshot stable)

コードレビューのチェックリスト

□ No `any` types (use `unknown` if needed)
□ No `// @ts-ignore` tanpa penjelasan
□ Error boundaries di route level
□ Loading states handled
□ Empty states handled
□ Error states handled  
□ Accessibility (aria labels, keyboard nav)
□ No hardcoded strings (i18n ready)
□ No console.log in production code
□ Tests untuk business logic

コメント