😸
Next.jsでloading.tsxが呼ばれるタイミング
はじめに
loading.tsx
はApp Routerを使用している場合に、特定の条件で呼ばれる。
loading.tsx
が呼ばれるタイミング
1. Suspenseのフォールバックとして
loading.tsxは、layout.tsxの子コンポーネントが非同期レンダリングされるときに自動的に表示されます。
例えば、次のようなloading.tsx
があるとします。
app/loading.tsx
export default function Loading() {
return <p>Loading...</p>;
}
この場合、次のような条件でloading.tsx
が表示される。
条件① ページコンポーネントが非同期
app/page.tsx
export default async function Page() {
await new Promise((resolve) => setTimeout(resolve, 2000)); // 2秒待機
return <h1>Home Page</h1>;
}
page.tsxのロードに時間がかかるため、loading.tsx
が一時的に表示される。
条件② レイアウトの子コンポーネントが非同期
app/layout.tsx
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div>
<h1>My App</h1>
{children}
</div>
);
}
app/some-page/page.tsx
export default async function SomePage() {
await new Promise((resolve) => setTimeout(resolve, 3000)); // 3秒待機
return <h1>Some Page</h1>;
}
some-page
が遅延ロードされると、その間loading.tsx
が表示される。
2. ネストしたルートの loading.tsx
ルートごとにloading.tsx
を定義できるため、app配下のディレクトリごとにloading.tsx
を作成すると、そのルートに対して適用されます。
例えば:
フォルダ構成
app/
├── layout.tsx
├── loading.tsx ← 全ページのローディングUI
├── page.tsx
├── dashboard/
│ ├── layout.tsx
│ ├── loading.tsx ← `/dashboard` 専用のローディングUI
│ ├── page.tsx
この場合、
-
/dashboard
にアクセスした場合はapp/dashboard/loading.tsx
-
/
やその他のページではapp/loading.tsx
が表示される。
loading.tsx が呼ばれない場合
以下のようなケースではloading.tsx
は表示されません。
-
ページが同期的にレンダリングされる場合
- async を使わずにコンポーネントがすぐにレンダリングされると loading.tsx は不要。
-
データフェッチがクライアントコンポーネント内で行われる場合
-
useEffect
でデータを取得する場合は、loading.tsx
ではなく、クライアントコンポーネント内でuseState
を使ってローディング状態を管理する必要がある。
-
-
suspenseを手動で使っていない場合
-
loading.tsx
は自動的にSuspense
のフォールバックとして適用されるが、ページコンポーネントやレイアウトが同期的にレンダリングされると適用されない。
-
Discussion