サスペンションのメカニズム、コンポーネントの遅延読み込み、バンドルの分割を習得します。
このレッスンを Kodokon で開くSuspense はあまり知られていないメカニズムに依存しています。まだデータやコードを持たないコンポーネントは、そのレンダリングを サスペンド(中断) します。内部的には、現在の実装は Promise をスローし、React はそれをちょうどエラーを傍受するのと同じように傍受します。React はその後 最も近い <Suspense> 境界 まで遡り、その fallback を表示し、Promise が解決されると サブツリーのレンダーを再実行 します。これは実装の詳細(自分で Promise をスローしてはいけません)ですが、観測できるすべての挙動を説明します。境界は非同期処理に対する宣言的な catch として振る舞うのです。歴史的なユースケースは React.lazy による コード分割 です。
import { lazy, Suspense } from 'react';
const Chart = lazy(() => import('./Chart'));
function Dashboard() {
return (
<Suspense fallback={<Spinner />}>
<Chart points={data} />
</Suspense>
);
}lazy は、default エクスポートを持つモジュール に解決される Promise を返す関数を期待します。分割そのものはバンドラーの仕事です。各動的 import() は分割点となり、別個のチャンク を生成して、必要に応じて読み込まれます。実際のコードベースでよくある微妙な点: あなたのコンポーネントはしばしば 名前付きエクスポート です。その場合、モジュールをその場で適合させる必要があります。
const Chart = lazy(() =>
import('./charts').then((module) => ({
default: module.Chart,
}))
);本番環境で厄介な部分: ナビゲーション の際、すでに表示されているコンテンツが再びサスペンドし(新しいルート、新しいチャンク)、突然 fallback に置き換えられることがあります。React 18 以降、startTransition でラップされた更新はこの挙動を変えます。React は新しいレンダーがバックグラウンドでサスペンドしている間、それまでのインターフェースを画面に残し 、まだ一度も表示されていないコンテンツについてのみ fallback を表示します。境界は深さ方向にも組み合わせられます。複数のネストした <Suspense> 境界により、グローバルなスケルトンから詳細に至るまで、インターフェースをゾーンごとに段階的に表示できます。
const [isPending, startTransition] = useTransition();
function openTab(nextTab) {
startTransition(() => {
setTab(nextTab);
});
}
// The current tab stays visible while the new
// one loads, instead of dropping back to the fallback.React.lazy に渡す関数は何を返す必要がありますか?