Next.js/ルーティング/Lesson 10
Layout vs Template — 状態を維持するか、毎回新たにマウントするか
25分·theory
このチャプター
2/3
TypeScript
Layout vs Template — 状態を維持するか、毎回新たにマウントするか
💡 なぜ学ぶ必要があるのか? — 状態が生き残るか消えるか
🎯
App Router では、ルート間を移動しても `layout.tsx` は再マウントされません — つまり、内部の `useState`・`useRef`・スクロール位置・再生中の動画がそのまま保持されます。
💼
これが望ましい場合もあれば(サイドバー・ヘッダー)、そうでない場合もあります(ページ移動のたびに入場アニメーションを再生したいときなど)。
⚡
`template.tsx` は `layout.tsx` と見た目は同じですが、**移動のたびに再マウント**されます — `useEffect` が毎回実行されます。
🔗
通常は 90% のケースで `layout` で十分です。`template` は特殊なケース(入場アニメーション・ページ単位のトラッキング・強制リセット)にのみ使用します。
🏢 실무에서는
codemaster40 のサイドバーは、カテゴリ間を移動しても同じ状態を維持します — これが `layout.tsx` の効果です。カテゴリ移動のたびにサイドバーの開閉状態がリセットされるなら、それは `template.tsx` で誤って実装されたケースです。逆に、ページごとに新しいフェードインアニメーションを表示したい場合は `template.tsx` が適切です。
Layout · Template · 状態保持モデル
1. layout.tsx — 子ルート間のナビゲーションでもマウントを維持
- ▸
/dashboard/posts→/dashboard/usersへ遷移したとき: layout はそのまま維持され、childrenだけが新しいページに差し替えられます。 - ▸layout 内の Client Component が
useStateを持っていれば、その state は保持されます。
2. template.tsx — 毎回新たにマウント
- ▸
/dashboard/posts→/dashboard/usersへ遷移したとき: template が新たにマウントされ → フェードインアニメーションが再度実行されます。 - ▸ページごとの入場アニメーションや、
useEffectをページ進入のたびに実行する必要があるページビュー計測に適しています。
3. 両方を同時に使うこともできる
レンダー順: layout > template > page。ナビゲーション時、layout は生き残り、template と page は毎回新たに生成されます。
4. 可視化 — 状態保持モデル
5. いつどちらを使う?
template は本当に必要なときだけ使いましょう。安易な template の使用 = 毎回のマウントコスト + 画面のちらつきを招きます。
💡 💡 Layout vs Template 判断ガイド
1. 基本は常に layout。template は「なぜ必要か」答えられるときだけ使う
安易な template の使用 = 毎回のマウントコスト + 意図しない state リセットによるユーザーの不満。
2. 「state がページ遷移をまたいで生き残るべきか?」を考える
- ▸はい → layout (サイドバー・グローバルシェル・再生中のビデオプレイヤー)
- ▸いいえ → template (ページごとにクリーンな状態で開始)
3. template が必要な明確なシグナル 3 つ
- ▸ページ遷移アニメーション (フェードイン・スライドイン)
- ▸ページビュー分析 —
useEffectをページ進入のたびに実行する必要がある - ▸フォームの自動リセット — 離脱後に戻っても空の状態
4. layout.tsx に 'use client' を付けても state は保持される
layout が Server Component であれ Client Component であれ、インスタンスが維持されるという事実は変わりません。Client layout の useState は正常に保持されます。
5. どちらも children のみを受け取る — ページの props を直接受け取ることはできない
layout・template ともに params は受け取れます (動的ルート) が、ページのデータ props を受け取ることはできません。データはページが自分で fetch します。
⚡ 自分で試してみよう — layout vs template のインスタンス追跡
ルート遷移のたびに layout と template がどのように異なる動作をするかをシミュレーションします。
✏️ JS 코드
📟 コンソール出力
▶ 実行ボタンを押してください
⚠️ ブラウザのサンドボックスで実行 — console.log()のみ対応、alert/fetchは不可
理解度チェッククイズ
サイドバーの「メニューの開閉」状態がカテゴリー遷移をまたいでもそのまま保持されるべき場合、そのサイドバーはどこに置くべきでしょうか?