コード分割

React.SuspenseReact.lazyの2つを一緒に使うことで、必要になった時に初めてコードを読み込んでコンポーネントとしてレンダリングするというフローを簡単に実装できます。

⚠️ この要素は SSR (サーバーサイドレンダリング)では使えません。その場合はその部分をうまく SSR 時には実行しないような処理として書く必要があります。

です。

まず適当に動的に読み込むコンポーネントを作ります。以下をlazy-child.jsとします。

import React from "react";

export default () => <div>Lazy Child</div>;

このコンポーネントを使って試してみます。

const LazyChild = React.lazy(() => import("./lazy-child"));

const App = () => {
  return (
    <React.Suspense fallback={<div>loading...</div>}>
      <LazyChild />
    </React.Suspense>
  );
}

LazyChildではReact.lazyでラップしてlazy-child.jsを動的に読み込む関数を中に置いてます。返される値はコンポーネントですが、このコンポーネントは必ずReact.Suspense以下に配置する必要があります。
もしそうしない場合A React component suspended while rendering, but no fallback UI was specified.というエラーになります。

React.Suspenseにはfallback属性を渡します。これはコードを読み込んでいる最中に変わりに表示される要素になります。この動作を分かりやすくする為に一時的に以下のように書き換えてみると分かりやすいです。これはわざと読み込みに2秒以上かかるようにしたコードです。

const LazyChild = React.lazy(async () => {
  await new Promise(r => {
    setTimeout(r, 2000);
  });
  return import("./lazy-child");
});