第5章:初心者必見!React Hooksと状態管理(Stateとは?)
前章ではサイトをデプロイしましたが、現状のサイトは「見る」だけで「インタラクティブ」ではありません。 「ボタンをクリックして数字を増やす」や「ポップアップを開閉する」機能を作りたい場合、Reactの核心となる魔法:**Hooks(状態フック)**を学ぶ必要があります。
従来のフロントエンドエンジニアは状態管理を習得するために分厚い公式ドキュメントを読み込み、Class Componentのライフサイクルを理解する必要がありました。しかしVibe Codingの世界では、「概念」さえ理解すれば、残りの複雑なコードはAIに任せられます。本章では最も平易な言葉で、Reactで最も重要な2つのHooksを完全にマスターできるよう解説します。
🧠 概念整理:State(状態)とは?
あなたのウェブページを「デジタル看板」と想像してください。 看板に「現在の予約人数:5人」と表示されている場合、この「5」が**State(状態)**です。
従来のウェブ(Vanilla JSやjQuery)では、5を6に変更したい場合、自分でDOMを操作する必要がありました:
- 画面上の
<span>タグを見つける - 元の数字を消す
- 新しい数字を書き込む これは実際の看板を消しゴムとマーカーで更新するようなもので、非常に手間がかかります。
しかしReactでは、システムに「私の頭の中の状態を1増やして」と伝えるだけで、Reactが自動的にこの状態を使用している画面上の全ての箇所を瞬時に更新します! これは「データ駆動ビュー(Data-driven View)」と呼ばれます。
この状態を記憶するツールがuseStateです。
🎣 実践演習:useState予約日数計算機
ビジネスで非常に一般的な機能「ショッピングカートの数量増減」や「予約日数計算機」を実装してみましょう。
🔥【Vibe Prompt実践呪文】 私はReact初心者です。
src/components/にDaysCalculator.tsxコンポーネントを作成してください。 要件:
useStateを使用して「予約日数(days)」を記録、デフォルト値は1- 画面上にマイナスボタン、日数を表示するテキスト、プラスボタンを水平配置
- ロジック制限:日数は最低1日、最大14日(制限に達した場合、ボタンをdisabledにし灰色に)
- 動的計算:下部に「総額」を動的に表示(1日NT$1,200と仮定し、自動乗算して3桁区切りカンマを追加)
- UIデザイン:Tailwind CSSでモダンなGlassmorphism(ガラス擬態)スタイルのカードをデザイン(軽い影付き)
- コードに超詳細な日本語コメントを追加し、
useStateの動作原理を説明してください
AIは美しいカウンターを生成します。生成された核心コードに注目:
const [days, setDays] = useState(1);
これがReactの最も古典的な構文で、配列を返します:
days:現在の日数を読み取る(変数)setDays:日数を変更するリモコン(関数)。プラスボタンがクリックされるとsetDays(days + 1)を実行し、画面が瞬時に再レンダリングされます!
👁️ 概念整理:useEffect(副作用)とは?
「何かが起こった時、自動的にもう一つ��ことを実行したい」場合があります。 例:
- ページ読み込み時、バックエンドから最新商品データを取得
- 予約日数変更時、この日数をブラウザの
localStorageに保存 - ユーザーがウィンドウを閉じる時、タイマーを停止
この「一つの変更が連鎖反応を起こす」または「外部システムとの連携」動作をReactでは**Effect(副作用)**と呼び、useEffectで処理します。
🔥【Vibe Prompt実践呪文(続き)】 先ほどの
DaysCalculator.tsxを修正してください。
useEffectを追加:「予約日数(days)」変更時、Console(開発者ツール)に"ユーザーが日数をX日に変更"と出力- さらに
useEffectを追加:コンポーネント「初回読み込み時」、ウェルカムメッセージのtoast通知を自動表示- 初心者向けに
useEffectのDependency Array(依存配列)の意味をコメントで説明
AIはこのキーコードを追加します:
// 例1:依存配列に要素あり
useEffect(() => {
console.log(`ユーザーが日数を${days}日に変更`);
}, [days]); // <- この角括弧がDependency Array
// 例2:依存配列が空
useEffect(() => {
toast.success("予約システムへようこそ!");
}, []); // <- 空配列は「初回読み込み時のみ実行」を意味
- 最初の例の角括弧内の
daysは:daysが変更された時のみ、内部コードを実行 - 2番目の例の空配列
[]は:依存関係なし=ページ初回読み込み時のみ1回実行(API接続でデータ取得に最適!)
⚠️ 【よくある落とし穴】無限ループ(Infinite Loop)
useEffect使用時、初心者が最も陥りやすい「無限ループ」地獄はPCをフリーズさせます。
悪い例:
const [count, setCount] = useState(0);
useEffect(() => {
setCount(count + 1); // 誤り!無限ループ発生
}, [count]);
何が起きる?
count変更を検知し、useEffect発動useEffect内でsetCount(count + 1)実行countが再変更され、useEffectが再発動... 1秒間に1万回実行され、ブラウザがクラッシュします。
Vibe Coder解法:ブラウザが固まったら、99%無限ループが原因です。useEffectコードを選択しAIに質問:「ページが固まりました。ここで無限ループが発生していますか?依存配列のロジックを修正してください」
💼 【ビジネス応用】ECサイトの「ショッピングカート」と「最近見た商品」
useStateとuseEffectをマスターすれば、ECサイトの核心となる収益エンジンを掌握したことになります。
応用1:サイト全体のカート状態(Context/Zustand連携)
ユーザーがどの商品をカートに入れたか状態管理で記憶できます。「カートに追加」(setCartItems)クリック時、右上カートアイコンの数字が瞬時に更新。この滑らかな体験がコンバージョン率を大幅向上させます。
応用2:「最近見た商品」トラッキング
useEffectを使用し、ユーザーが商品ページにアクセス(コンポーネント読み込み)時、即座にAPIを発動し商品IDをデータベースの「閲覧履歴」リストに記録。
このデータを元にホームページで「あなたへのおすすめ(最近の閲覧履歴より)」を表示。この機能は業界で客単価15%向上が実証されています!
次章では、これら2つの基本概念を組み合わせ、ウェブ開発で最も複雑かつ価値のある領域に挑戦します:Supabaseを使った会員ログイン画面の実装!