Skip to content

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 with React.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 unwrap params with React.use().

このエラーは、以下のような典型的な動的ルートのコードで発生します:

tsx
export default async function Page({ params }: { params: { id: string } }) {
  const id = params.id; // ここでエラーが発生
  return <div>Product ID: {id}</div>;
}

解決策

Next.js 15では、paramsPromiseオブジェクトになりました。これはNext.jsの設計上の変更であり、今後のバージョンで必須となる予定です。以下の方法で適切に扱うことができます。

方法1: サーバーコンポーネントでのasync/await使用

サーバーコンポーネントでは、async/awaitを使用してparamsをアンラップします:

tsx
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()フックを使用します:

tsx
'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を抽出し、クライアントコンポーネントにプロパティとして渡す方法も有効です:

tsx
// 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} />;
}
tsx
// app/product/[id]/productPage.tsx (クライアントコンポーネント)
"use client";

export default function ProductPage({ id }: { id: string }) {
  return <div>{id}</div>;
}

背景

この変更はNext.js 15の重要なアップデートの一つです。paramsPromiseにすることで:

  • データ取得の最適化: 並行したデータ取得が可能になり、パフォーマンスが向上
  • 将来の機能への対応: Reactの非同期レンダリング機能との互換性を確保
  • 型安全性の向上: 非同期処理が型システムで明示的に表現される

INFO

現時点では従来の直接アクセスもサポートされていますが、将来のバージョンでは必須となるため、早めの移行を推奨します。

まとめ

Next.js 15では、paramsオブジェクトがPromiseになったため、適切な方法でアンラップする必要があります:

  • サーバーコンポーネント: await paramsを使用
  • クライアントコンポーネント: use(params)を使用
  • 複合的なケース: サーバーコンポーネントで抽出してクライアントに渡す

この変更はパフォーマンス向上と将来の機能拡張のための重要なステップです。現在のコードベースを更新して、将来のNext.jsバージョンに備えましょう。