Next.js 15のparamsがPromiseになった件と適切な扱い方
問題
Next.js 15にアップグレードした後、動的ルートでparams
にアクセスすると次のエラーが発生するようになりました:
A param property was accessed directly with
params.id
.params
is now a Promise and should be unwrapped withReact.use()
before accessing properties of the underlying params object. In this version of Next.js direct access to param properties is still supported to facilitate migration, but in a future version, you will be required to unwrapparams
withReact.use()
.
このエラーは、以下のような典型的な動的ルートのコードで発生します:
export default async function Page({ params }: { params: { id: string } }) {
const id = params.id; // ここでエラーが発生
return <div>Product ID: {id}</div>;
}
解決策
Next.js 15では、params
がPromise
オブジェクトになりました。これはNext.jsの設計上の変更であり、今後のバージョンで必須となる予定です。以下の方法で適切に扱うことができます。
方法1: サーバーコンポーネントでのasync/await使用
サーバーコンポーネントでは、async/await
を使用してparams
をアンラップします:
export default async function Page({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
return <div>Product ID: {id}</div>;
}
TIP
サーバーコンポーネントではasync
関数を使用できるため、await
による解決が最もシンプルな方法です。
方法2: クライアントコンポーネントでのReact.use()使用
クライアントコンポーネントでparams
を使用する場合は、Reactのuse()
フックを使用します:
'use client';
import { use } from 'react';
export default function Page({ params }: { params: Promise<{ id: string }> }) {
const { id } = use(params);
return <div>Product ID: {id}</div>;
}
WARNING
クライアントコンポーネントではasync/await
が使用できないため、必ずuse()
フックを使用してください。
方法3: サーバーコンポーネントで抽出してクライアントに渡す
複雑なコンポーネント構造の場合、サーバーコンポーネントでparams
を抽出し、クライアントコンポーネントにプロパティとして渡す方法も有効です:
// app/product/[id]/page.tsx (サーバーコンポーネント)
import ProductPage from "./productPage";
export default async function Page({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
return <ProductPage id={id} />;
}
// app/product/[id]/productPage.tsx (クライアントコンポーネント)
"use client";
export default function ProductPage({ id }: { id: string }) {
return <div>{id}</div>;
}
背景
この変更はNext.js 15の重要なアップデートの一つです。params
をPromise
にすることで:
- データ取得の最適化: 並行したデータ取得が可能になり、パフォーマンスが向上
- 将来の機能への対応: Reactの非同期レンダリング機能との互換性を確保
- 型安全性の向上: 非同期処理が型システムで明示的に表現される
INFO
現時点では従来の直接アクセスもサポートされていますが、将来のバージョンでは必須となるため、早めの移行を推奨します。
まとめ
Next.js 15では、params
オブジェクトがPromise
になったため、適切な方法でアンラップする必要があります:
- サーバーコンポーネント:
await params
を使用 - クライアントコンポーネント:
use(params)
を使用 - 複合的なケース: サーバーコンポーネントで抽出してクライアントに渡す
この変更はパフォーマンス向上と将来の機能拡張のための重要なステップです。現在のコードベースを更新して、将来のNext.jsバージョンに備えましょう。