Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

likeornament 님의 블로그

[Next.js] params가 갑자기 Promise? Next.js 15가 바꿔놓은 것들 본문

공부/next.js

[Next.js] params가 갑자기 Promise? Next.js 15가 바꿔놓은 것들

likeornament 2025. 4. 14. 16:14

본인은 Next.js 14 버전을 쓰다가 15버전으로 업데이트한 뒤 기존처럼 작업을 진행하던 중, 예상치 못한 오류를 마주했다.

// pr/[studyId]/page.tsx
type Props = {
  params: { 
    studyId: string,
  }
}

export default function PRPage({ params }: Props) {
	const { studyId } = params;
	...
}

 

위 코드처럼 params 타입을 정의하고, 컴포넌트 내부에서 studyId를 구조분해 할당하여 사용하려 했다.
그런데 다음과 같은 TypeScript 오류가 발생했다.

 

Type 'Promise<{ studyId: string; }>' is not assignable to type '{ studyId: string; }'.
  Property 'studyId' is missing in type 'Promise<{ studyId: string; }>' but required in type '{ studyId: string; }'

"갑자기 Promise?"

혹시나 싶어 Next.js 15의 변경 내용을 살펴보니 원인을 찾을 수 있었다.

 

✅ Next.js 15의 변경 사항

Next.js 15에서는 params, searchParams, segment 등이 자동으로 lazy-evaluated Promise로 전달된다.

즉, 이전 버전처럼 단순 객체로 받으면 안 되고, 비동기(Promise) 형태로 처리해야 한다.

 

따라서 위 코드의 경우 params가 아직 Promise 상태라서 구조분해 할당 시 런타임에서 오류가 발생하게 된다.

 

🔧 해결 방법

type Props = {
  params: Promise<{ 
    studyId: string,
  }>
}

export default async function PRPage({ params }: Props) {
  const { studyId } = await params;
  ...
}

paramsPromise 타입으로 선언하고, await을 붙이면 문제없이 동작한다.

// word/page.tsx
type Props = {
  searchParams: Promise<{
    studyId: string;
    wordTotal: string;
  }>
}

export default async function WordPage({ searchParams }: Props) {
  const { studyId, wordTotal } = await searchParams;
  ...
}

searchParams도 마찬가지로 Promise 타입으로 처리해야 한다.


이처럼 Next.js 15에서는 페이지 컴포넌트에서 받는 params, searchParams 등이 자동으로 Promise가 되므로, 이를 await 처리하는 방식으로 코드를 수정해야 한다.
버전 업데이트 시 반드시 릴리즈 노트를 확인하는 습관이 중요하다는 걸 다시금 느끼게 해준 경험이었다.