第3章:スパゲッティコード大掃除:AIにReactコンポーネントのリファクタリングと分割を依頼する

Vibe Codingでは、迅速さを求めるあまり、新しい機能を同じファイルに追加し続けることがよくあります。やがて、page.tsxが800行、さらには1500行以上に膨れ上がることも。こうなると、AIは次第に賢くなくなり、Aを修正したらBが壊れるといった事態が発生します。

このようにごちゃごちゃで互いに絡み合ったコードを「スパゲッティコード(Spaghetti Code)」と呼びます。本章では、AIに指示を出して安全に「コードリファクタリング(Refactoring)」と「コンポーネント分割」を行う方法を学びます。

なぜファイルが大きいとAIは賢くなくなるのか?

  1. Context Windowの浪費:AIは毎回の会話でファイル全体を読み込む必要があります。1500行のファイルは大量のTokenを消費し、AIが最初の要件を「忘れる」原因になります。
  2. 修正リスクの高さ:1つのファイルにHeader、Sidebar、Main Content、Footerが詰め込まれている場合、AIにFooterの修正を依頼すると、誤ってHeaderの状態(State)を変更してしまう可能性があります。
  3. 人間が理解できない:Vibe Codingは人間がコードを読まなくてよいという意味ではありません。ファイルが大きすぎて把握できなくなると、プロジェクトのコントロールを失います。

リファクタリングの黄金律:単一責任の原則(SRP)

AIにコンポーネントを分割させる前に、「単一責任」の概念を頭に叩き込む必要があります。 Reactコンポーネントは「1つのこと」だけを担当すべきです。

例えば、PricingPageは以下のすべてを担当すべきではありません:

  • データベースから価格プランを取得する
  • プランカードのUIをレンダリングする
  • 決済ボタンのStripe APIロジックを処理する
  • よくある質問(FAQ)アコーディオンをレンダリングする

代わりに、以下のように分割すべきです:

  • PricingPage(組み合わせのみ担当)
    • PricingCard(カードUIのレンダリングのみ担当)
    • CheckoutButton(決済ロジックのみ担当)
    • FaqSection(FAQロジックのみ担当)

実践:コンポーネント分割の「詠唱」方法

AIに「このファイルを小さく分割して」とだけ伝えるのは曖昧すぎます。AIが理解不能な構造を提案する可能性があります。

代わりに、以下のリファクタリング専用Promptテンプレートを使用してください:

[タスク目標] 現在のsrc/app/pricing/page.tsxファイルが長すぎるため、保守性を向上させるためにリファクタリングとコンポーネント分割を行いたい。

[分割計画] 以下の3つのファイルにコードを分割してください:

  1. src/components/pricing/PricingCard.tsx:単一のプランカードUIをレンダリングする。tier(プランデータ)をPropsとして受け取る。
  2. src/components/pricing/FaqSection.tsx:下部のよくある質問をレンダリングし、アコーディオンの開閉状態(useState)を含む。
  3. src/app/pricing/page.tsx:メインページとして残し、上記2つのコンポーネントをインポートし、データ取得ロジックを保持する���

[実行要件]

  1. ステップバイステップで進め、まずPricingCard.tsxの完全なコードを提供してください。
  2. TypeScriptのInterface/Type定義が正しくエクスポートされ、共有されていることを確認してください。
  3. 既存のTailwindスタイルとアニメーションが完全に維持されていることを確認してください。

分割プロセスでの地雷回避

AIが分割後のコードを提供し始めたら、以下の点に注意してください:

1. Propsの受け渡し(Prop Drilling)

コンポーネントを分割すると、親ページ内の変数(例:const [isLoading, setIsLoading] = useState(false))が子コンポーネントで利用できなくなります。AIはこれらの変数をPropsとして渡す必要があります。もしAIが忘れていたら、「isLoadingをPricingCardにpropとして渡すのを忘れていない?」とリマインドしてください。

2. 絶対パス vs 相対パス

src/components/に分割すると、元のファイル内のimportパスが間違っている可能性があります。 AIが書いたimportを確認してください: ✅ import { AlertCircle } from "lucide-react";import { cn } from "@/lib/utils";import { cn } from "../../lib/utils";(Next.jsでは@/絶対パスを使用するのがベスト)

3. 一度に1つのことだけを行う

絶対ルール:リファクタリング中に新機能を追加しないでください! ボタンを分割しながら、同時にLoadingスピナーアニメーションを追加したい場合は、2ステップで行ってください。 ステップ1:分割。動作をテスト。 ステップ2:アニメーション追加。 これにより、いつでもGit Commitで安全なポイントに戻れるようになります。

定期的な大掃除のメリット

ファイルが300行を超えたらAIに「コンポーネント分割」を依頼する習慣を身につけると、以下のようなメリットがあります:

  • AIのコーディング速度が向上(Tokenが減るため)。
  • Bugが減少(状態が各コンポーネントに隔離されるため)。
  • 自分でコードを読むのが楽しくなる。

これが、Vibe Codingで大規模な商業プロジェクトを長期的に維持する究極の秘訣です!

章のまとめ

  • コアコンセプトと原理を理解
  • 実装方法とテクニックを習得
  • 一般的な問題と解決策に精通
  • 実際のプロジェクトに適用可能

さらに読む

  • 公式ドキュメントとAPIリファレンス
  • GitHubのオープンソース例
  • 技術書とオンラインコース
  • コミュニティディスカッションと技術ブログ

実装例

基本例

# 完全な実装例を提供します

手順

  1. セットアップ: 開発環境の設定
  2. データ: 必要なデータの準備
  3. 実装: コア機能の構築
  4. テスト: 動作確認
  5. 最適化: パフォーマンスの向上

よくあるエラー

| エラー種別 | 原因 | 解決方法 | |-----------|------|---------| | コンパイル | 構文 | コードの構文を確認 | | 実行時 | 環境 | 依存パッケージの確認 | | 論理 | アルゴリズム | ステップごとのデバッグ | | パフォーマンス | 効率 | プロファイラーの使用 |

コード例

import sys

def main():
    print("Hello, World!")

if __name__ == "__main__":
    main()

参考資料

  • 公式ドキュメント
  • APIリファレンス
  • オープンソース例
  • コミュニティディスカッション

完全なチュートリアルをロック解除

このチャプターは有料コンテンツです。プロジェクトに参加して、10以上の神レベルのPromptや実際のソースコード例を含む、5000字以上の深い分析をロック解除してください!