動的APIは非同期です
特定のAPIに同期的にアクセスすると警告が表示されるようになった理由について詳しく説明します。
この警告が発生した理由
コードのどこかで、動的レンダリングをオプトインするAPIを使用しました。
動的APIは
- ページ、レイアウト、メタデータAPI、ルートハンドラに提供される
params
およびsearchParams
プロップ。 next/headers
からのcookies()
、draftMode()
、headers()
Next 15 では、これらのAPIが非同期になりました。詳細については、Next.js 15 のアップグレードガイドを参照してください。
例えば、以下のコードは警告を発します
function Page({ params }) {
// direct access of `params.id`.
return <p>ID: {params.id}</p>
}
これには、これらのAPIの戻り値を列挙(例: {...params}
、Object.keys(params)
)したり、反復処理(例: [...headers()]
や for (const cookie of cookies())
、または明示的に cookies()[Symbol.iterator]()
)したりすることも含まれます。
この警告を発したNext.jsのバージョンでは、これらのプロパティへの直接アクセスはまだ可能ですが、警告が表示されます。将来のバージョンでは、これらのAPIは非同期になり、直接アクセスは期待通りに動作しません。
修正方法の可能性
next-async-request-api
codemod はこれらのケースの多くを自動的に修正できます
$ npx @next/codemod@canary next-async-request-api .
codemod はすべてのケースをカバーできるわけではないため、手動でコードを調整する必要がある場合があります。
警告がサーバー(例: ルートハンドラ、またはサーバーコンポーネント)で発生した場合は、動的APIのプロパティにアクセスするために await
する必要があります
async function Page({ params }) {
// asynchronous access of `params.id`.
const { id } = await params
return <p>ID: {id}</p>
}
警告が同期コンポーネント(例: クライアントコンポーネント)で発生した場合は、まず React.use()
を使用してPromiseをアンラップする必要があります
'use client'
import * as React from 'react'
function Page({ params }) {
// asynchronous access of `params.id`.
const { id } = React.use(params)
return <p>ID: {id}</p>
}
移行できないケース
Next.js codemod が codemod で移行できないものを見つけた場合、@next-codemod-error
プレフィックスと推奨されるアクションを含むコメントを残します。例: この場合、cookies()
の呼び出しを手動で await し、関数を async に変更する必要があります。その後、関数の使用箇所を適切に await するようにリファクタリングします
export function MyCookiesComponent() {
const c =
/* @next-codemod-error Manually await this call and refactor the function to be async */
cookies()
return c.get('name')
}
Linterによる強制移行
codemod によって残された @next-codemod-error
で始まるコメントに対処しなかった場合、Next.js は開発とビルドの両方でエラーを発生させ、問題に対処するよう強制します。変更点を確認し、コメントの提案に従ってください。必要な変更を行いコメントを削除するか、コメントのプレフィックス @next-codemod-error
を @next-codemod-ignore
に置き換えることができます。何もアクションをとる必要がない場合は、コメントのプレフィックス @next-codemod-ignore
がビルドエラーをバイパスします。
- /* @next-codemod-error <suggested message> */
+ /* @next-codemod-ignore */
知っておくと良いこと:
Promise のアンラップ (
await
またはReact.use
のいずれか) を、実際にその値を消費する必要があるまで遅らせることができます。これにより、Next.js はページのより多くの部分を静的にレンダリングできるようになります。
この情報は役に立ちましたか?