非同期コンポーネント
CoddyのReactジャーニー「Next.js の基本」セクションの一部 — レッスン 23/47。
前章で準備したすべての成果がここにあります。サーバーコンポーネントは async にすることができます:
import { getDishes } from '../lib/data';
export default async function Page() {
const dishes = await getDishes();
return <h1>{dishes.length} dishes</h1>;
}もう一度読んでみてください。これは本当に画期的なことです。コンポーネントは待ちます。Next.jsはそれをサーバー上で実行し、awaitの処理を完了させ、それから初めて結果をHTMLに変換します。
ブラウザー専用で記述する場合と比較してみましょう。
- ページは最初に空でレンダリングされます
- ページが読み込まれた後にリクエストが送信されます
- 状態が切り替わり、コンテンツが表示されます。これはユーザーが毎回目にするチラつき(フリッカー)となります
async サーバーコンポーネントでは、最初の空のレンダリングは発生しません。HTML が構築された時点で data は既に存在しているため、チラつきが発生する理由がありません。useEffect も、ローディングフラグも、2回目のリクエストも不要です。
2つのルールによりこれが可能になります:
asyncにできるのは server コンポーネントのみです:'use client'と記述されたコンポーネントはasyncにできません- データは、データベース、ファイル、または
lib/data.jsのようなモジュールなど、サーバーがアクセスできる場所から取得する必要があります
チャレンジ
簡単lib/data.js は提供されており、ロックされています。これは { id, name } オブジェクトの配列を返す Promise を返却する getDishes() をエクスポートしています。
app/page.jsx内のPageをasync関数にします。getDishes()をawaitしてdishes変数に代入します。<ul id="dish-list">の内部に、dishごとに1つの<li>をレンダリングし、key={dish.id}、id={dish.id}、およびテキストとしてdishのnameを設定します。
useEffect やローディングフラグは不要です。ただ await するだけです。
自分で試してみよう
import './globals.css';
export const metadata = {
title: 'My App',
};
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
</body>
</html>
);
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。