hhjeee.log
GitHub Icon

Next.js15의 dynamic API 비동기화

2024년 12월 24일


문제상황

아래와 같이 params의 요소들을 받아와 함수로 넘겨주고 있었는데 경고가 발생했다.

const PostPage = ({
  params,
}: {
  params: { category: string; slug: string };
}) => {
  const { meta, content } = getPostData(params.category, params.slug);

Server Error: Route "/posts/[category]/[slug]" used params.category. params should be awaited before using its properties.
Server Error: Route "/posts/[category]/[slug]" used params.slug. params should be awaited before using its properties.

Next.js 15에서의 변화

next.js15에서 업그레이드된 사항들 중 Async Request API 파트를 살펴보자.

Async Request APIs (Breaking change)

Previously synchronous Dynamic APIs that rely on runtime information are now asynchronous:

  • cookies
  • headers
  • draftMode
  • params in layout.js, page.js, route.js, default.js, opengraph-image, twitter-image, icon, and apple-icon.
  • searchParams in page.js

To ease the burden of migration, a codemod is available to automate the process and the APIs can temporarily be accessed synchronously.

Next.js 15에서는 동기적으로 처리되던 Dynamic API가 비동기적으로 변경되었다. params의 경우도 이 dynamic API에 포함되며, 코드에서 동기적으로 사용하고 있었기 때문에 오류가 발생했던 것 !

해결

공식문서에서 제공하는 해결방안을 살펴보자.

비동기로 변경

Next.js는 서버 컴포넌트에서 params를 비동기적으로 처리해야 한다고 경고하고 있다. 이를 해결하려면, params를 await를 사용해 비동기적으로 접근해야 한다.

구조 분해 할당에서 await를 사용해 비동기적 접근하는 방식으로 변경하는 방식으로 해결 !

const PostPage = async ({
  params,
}: {
  params: { category: string; slug: string };
}) => {
  const { category, slug } = await params;
  const { meta, content } = getPostData(category, slug);

클라이언트 컴포넌트라면

만약 클라이언트 컴포넌트에서 동일한 경고가 발생한 경우, React.use()를 사용하여 Promise 값 처리할 수 있다.

'use client';
 
import { use } from 'react';
 
const PostPage = ({
  params,
}: {
  params: Promise<{ category: string; slug: string }>;
}) => {
  const { category, slug } = use(params); // React.use() 사용
  const { meta, content } = getPostData(category, slug);
};