💨

久しぶりに触るNext.js: loading.tsxとSuspenseについて

2025/01/07に公開

loading.tsxSuspenseの使い分け方を学んだので、この記事で共有したいと思います。


loading.tsxとは?

Next.jsのloading.tsxファイルは、App Routerでの特定のルートのローディング状態を簡単に実装するために導入されました。このファイルを作成すると、ルートが非同期データを取得している間に表示するUIを定義できます。

例えば、以下のようにルートにloading.tsxを追加できます。

// app/dashboard/loading.tsx
export default function Loading() {
  return <p>Loading dashboard...</p>;
}

これにより、/dashboardにアクセスした際、非同期処理中に「Loading dashboard…」というメッセージが表示されます。

特徴

  • ルート単位でローディングUIを定義
  • 非同期データ取得の最中に自動的に表示
  • 簡潔で実装コストが低い

ReactのSuspenseとは?

一方、ReactのSuspenseは、コンポーネント単位でローディング状態を管理するための強力なツールです。これにより、ページ全体ではなく、特定の非同期コンポーネントのローディングUIをカスタマイズできます。

以下は、Suspenseを使用した例です。

import { Suspense } from 'react';
import MyComponent from './MyComponent';

export default function Page() {
  return (
    <Suspense fallback={<p>Loading component...</p>}>
      <MyComponent />
    </Suspense>
  );
}

特徴

  • コンポーネント単位で柔軟にローディングUIを設定
  • 非同期コンポーネントのレンダリングを制御
  • 再利用性が高い

使い分けのポイント

両者の違いを踏まえると、それぞれ適切なシナリオで使用することが重要です。

使用場面 loading.tsx Suspense
対象範囲 ルート全体 個別のコンポーネント
実装の手軽さ 非常に簡単 若干の工夫が必要
再利用性 低い 高い
細かい制御 難しい 容易

実際のユースケース

  • loading.tsx: ページ全体で共通のローディングUIを設定したい場合

    • 例: ダッシュボード全体のローディング
  • Suspense: ページ内の特定のコンポーネントのみローディングUIを表示したい場合

    • 例: サイドバーやチャートデータの読み込み

実践例: 両方を組み合わせる

loading.tsxとSuspenseは同時に使用することも可能です。例えば、以下のように設定できます。

// app/dashboard/loading.tsx
export default function Loading() {
  return <p>Loading dashboard...</p>;
}

// app/dashboard/page.tsx
import { Suspense } from 'react';
import Chart from './Chart';

export default function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      <Suspense fallback={<p>Loading chart...</p>}>
        <Chart />
      </Suspense>
    </div>
  );
}

この例では、以下のような挙動になります。

  1. /dashboard全体のロード中はloading.tsxが表示される。
  2. ページのレンダリング後、Chartコンポーネントのロード中にはSuspenseのfallbackが表示される。

まとめ

loading.tsxとSuspenseは、それぞれ異なる目的でローディングUIを実装するための強力なツールです。使い分けを意識し、状況に応じてこれらを活用することで、よりスムーズなユーザー体験を提供できるでしょう。

Discussion