0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.js 15における動的ルーティングパラメータの非同期化対応

Posted at

Next.js 15における動的ルーティングパラメータの非同期化対応

Next.js 15では、動的ルーティングパラメータ(params)が非同期APIとして変更されました。
実装の際に詰まったので記録として残します!

発生する問題

Next.js 15にアップグレードした後、以下のようなエラーメッセージが表示されることがあります:

Error: Route "/patients/[id]" used `params.id`. `params` should be awaited before using its properties. 
Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis

このエラーは、paramsオブジェクトのプロパティ(例:params.id)を直接参照した場合に発生します。

問題のあるコード例

export default async function PatientDetailPage({ params }: PatientPageProps) {
  try {
    const patient = await prisma.patient.findUnique({
      where: { id: params.id }, // ここがエラーの原因
      // ...
    });
    // ...
  } catch (error) {
    // ...
  }
}

修正方法

修正方法は簡単です。paramsオブジェクトをawaitキーワードで非同期に解決してから、そのプロパティにアクセスします:

export default async function PatientDetailPage({ params }: PatientPageProps) {
  try {
    // paramsを非同期に解決してからidを抽出
    const { id } = await params;
    
    const patient = await prisma.patient.findUnique({
      where: { id }, // 抽出したidを使用
      // ...
    });
    // ...
  } catch (error) {
    // ...
  }
}

修正例:患者詳細ページ

export default async function PatientDetailPage({ params }: PatientPageProps) {
  try {
    // paramsを非同期に解決
    const { id } = await params;
    
    const patient = await prisma.patient.findUnique({
      where: { id },
      include: {
        clinic: true,
        createdBy: {
          select: {
            id: true,
            name: true,
            email: true,
          },
        },
        analysisSessions: {
          take: 5,
          orderBy: {
            sessionDate: "desc",
          },
        },
      },
    });

    if (!patient) {
      notFound();
    }
    
    // 以下、既存のコード...
  } catch (error) {
    // エラーハンドリング...
  }
}

修正例:患者編集ページ

export default async function PatientEditPage({ params }: PatientPageProps) {
  // paramsを非同期に解決
  const { id } = await params;

  // 患者データを取得
  const patient = await prisma.patient.findUnique({
    where: { id },
  });

  // 患者が見つからない場合は404ページを表示
  if (!patient) {
    notFound();
  }

  return (
    // JSXの部分...
  );
}

技術的解説

Next.js 15では、以下の動的APIが非同期になりました:

  • ページ、レイアウト、メタデータAPI、ルートハンドラーに提供される paramssearchParams
  • next/headers からの cookies(), draftMode(), headers()

この変更により、Next.jsはレンダリングの最適化を改善し、パフォーマンスを向上させることができます。関数が既に async でマークされていれば、単に await キーワードを追加するだけで対応できます。

クライアントコンポーネントでの対応

サーバーコンポーネント(上記の例)では await を使用しますが、クライアントコンポーネント('use client' でマークされたコンポーネント)では React.use() を使用する必要があります:

'use client'
import * as React from 'react'

function Page({ params }) {
  // クライアントコンポーネントでの非同期アクセス
  const { id } = React.use(params)
  return <p>ID: {id}</p>
}

自動修正ツール

Next.jsは、この問題を自動的に修正するためのコードモッドを提供しています:

npx @next/codemod@canary next-async-request-api .

ただし、すべてのケースをカバーできるわけではないため、手動での調整が必要な場合もあります。

まとめ

Next.js 15では、動的ルーティングパラメータが非同期APIとなりました。この変更に対応するには:

  1. パラメータにアクセスする前に await キーワードを使用する
  2. 分割代入で必要なプロパティを抽出する
  3. 抽出したプロパティを使用する

これらの変更を加えることで、Next.js 15の新しい非同期APIモデルに対応し、アプリケーションのパフォーマンスを最大限に引き出すことができます。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?