第67章:loading.tsx を“区間ごと”に置く⏳💡
この章では、**ページ全体じゃなくて「この部分だけ待ってね〜」**を作れるようにするよ〜!🥰
Next.js の App Router は、フォルダ(=区間/セグメント)ごとに loading.tsx を置けるのが強いんだ〜✨
1) 「区間(セグメント)」ってなに?🧩
App Router では、app/ 配下の フォルダ1個 = だいたい1区間(Route Segment) だよ📁
その区間が表示されるとき、**中の Server Component が待ち(suspend)**になると、loading.tsx が “待ち画面” として出せるよ〜⏳✨ (Next.js)
2) loading.tsx の超ルール✅
app/○○/loading.tsxを置くと、その区間(○○)の読み込み中に表示される⏳- さらにネストした
app/○○/△△/loading.tsxを置くと、もっと内側の区間だけに効かせられる🪄 loading.tsxは 自動で Suspense 境界を作ってくれる(だから簡単!)✨ (Next.js)
3) 図でイメージしよう🧠✨(どこに置くと、どこが待つ?)
ポイントはこれ👇✨
/dashboardに行く → dashboard/loading.tsx が効く⏳/dashboard/settingsに行く → settings/loading.tsx が効いて、外側(dashboardの枠)は残りやすい🧡
4) ハンズオン:区間ごとローディングを体験しよう🎮✨
ゴール🏁
/dashboardは dashboard の待ちUI/dashboard/settingsは settings の待ちUI をそれぞれ見えるようにするよ〜!👀💕
手順A:ページを用意する📄
① app/page.tsx(入口ページ)
import Link from "next/link";
export default function Home() {
return (
<main style={{ padding: 24, fontFamily: "system-ui" }}>
<h1>デモ:区間ごと loading.tsx ⏳</h1>
<ul style={{ lineHeight: 2 }}>
<li>
<Link href="/dashboard" prefetch={false}>
/dashboard へ行く👉
</Link>
</li>
<li>
<Link href="/dashboard/settings" prefetch={false}>
/dashboard/settings へ行く👉
</Link>
</li>
</ul>
<p style={{ marginTop: 16, opacity: 0.8 }}>
※ prefetch を切ると、ローディングが目で見えやすいよ〜👀✨
</p>
</main>
);
}
prefetch={false}は「先読みしないでね」の指定だよ🫶 先読みがあると速すぎて、ローディングが一瞬で終わって見えないことがあるの🥹 (Next.js)
手順B:/dashboard 区間を作る📁
② app/dashboard/layout.tsx(枠)
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<section style={{ padding: 24, borderTop: "1px solid #ddd" }}>
<header style={{ marginBottom: 12 }}>
<strong>Dashboard の枠だよ🧱✨</strong>
</header>
{children}
</section>
);
}
③ app/dashboard/page.tsx(わざと遅くする🐢)
const wait = (ms: number) => new Promise((r) => setTimeout(r, ms));
export default async function DashboardPage() {
await wait(1500); // わざと遅延🐢
return (
<div>
<h2>/dashboard 📊</h2>
<p>読み込み終わったよ〜!🎉</p>
</div>
);
}
④ app/dashboard/loading.tsx(dashboard区間の待ちUI⏳)
export default function LoadingDashboard() {
return (
<div style={{ padding: 24 }}>
<p style={{ fontSize: 18 }}>Dashboard を読み込み中…⏳✨</p>
<p style={{ opacity: 0.7 }}>ちょっと待ってね〜☺️</p>
</div>
);
}
手順C:もっと内側の /dashboard/settings 区間を作る🪄
⑤ app/dashboard/settings/page.tsx(さらに遅くする🐢)
const wait = (ms: number) => new Promise((r) => setTimeout(r, ms));
export default async function SettingsPage() {
await wait(2000); // さらに遅延🐢🐢
return (
<div>
<h2>/dashboard/settings ⚙️</h2>
<p>設定ページだよ〜!🎀</p>
</div>
);
}
⑥ app/dashboard/settings/loading.tsx(settings区間だけの待ちUI⏳)
export default function LoadingSettings() {
return (
<div style={{ padding: 24 }}>
<p style={{ fontSize: 18 }}>設定を読み込み中…⚙️⏳</p>
<p style={{ opacity: 0.7 }}>ここだけ先に待ち表示できるのが強い✨</p>
</div>
);
}
5) 「区間ごと」だと何がうれしいの?🥰
たとえば /dashboard/settings に移動するとき👇
Dashboard の枠(layout)は残しつつ、settings 部分だけ loading にできるから、体感がめちゃ良くなるよ〜✨ (Next.js)
6) よくある「見えない!」問題あるある🥹🧯
- 速すぎて見えない:prefetch やキャッシュで一瞬で終わることあるよ〜💨
→
prefetch={false}で確認がラク👀 (Next.js) - ファイル名ミス:
loading.tsx(綴り大事!) - どこに置けばいいか迷子: → “待たせたい区間のフォルダ直下” に置く!📁✨ (Next.js)
- Route Group
(group)を使ってる:URLに出ないけど、整理用フォルダとして使えるよ📦(もちろんこの中にloading.tsxも置ける) (Next.js)
7) ミニチェック(3問)📝✨
app/dashboard/loading.tsxは、どの区間の待ちUI?🤔/dashboard/settingsを “settingsだけ” ローディングにしたい時、どこにloading.tsxを置く?📁- ローディングが見えない時に、まず疑うといいのは?💨
(答え)
- dashboard 区間
app/dashboard/settings/loading.tsx- prefetch/キャッシュで速すぎる、ファイル位置ミス、ファイル名ミス など!
まとめ🎀
loading.tsxは フォルダ(区間)ごとに置ける⏳✨- ネストすればするほど、“必要な場所だけ待たせる” ができてUXが良くなる🫶
prefetch={false}で挙動確認もしやすいよ👀💕 (Next.js)