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、ルートハンドラーに提供される
params
とsearchParams
-
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となりました。この変更に対応するには:
- パラメータにアクセスする前に
await
キーワードを使用する - 分割代入で必要なプロパティを抽出する
- 抽出したプロパティを使用する
これらの変更を加えることで、Next.js 15の新しい非同期APIモデルに対応し、アプリケーションのパフォーマンスを最大限に引き出すことができます。
参考