Menu
Coddy logo textTech

非同期コンポーネント

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 のようなモジュールなど、サーバーがアクセスできる場所から取得する必要があります
challenge icon

チャレンジ

簡単

lib/data.js は提供されており、ロックされています。これは { id, name } オブジェクトの配列を返す Promise を返却する getDishes() をエクスポートしています。

  1. app/page.jsx 内の Pageasync 関数にします。
  2. getDishes()await して dishes 変数に代入します。
  3. <ul id="dish-list"> の内部に、dish ごとに1つの <li> をレンダリングし、key={dish.id}id={dish.id}、およびテキストとして dishname を設定します。

useEffect やローディングフラグは不要です。ただ await するだけです。

自分で試してみよう

import './globals.css';

export const metadata = {
    title: 'My App',
};

export default function RootLayout({ children }) {
    return (
        <html lang="en">
            <body>
                {children}
            </body>
        </html>
    );
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

Next.js の基本のすべてのレッスン