URL Shortener 프로젝트를 만들면서 /stats/[code] 페이지에서 특정 코드의 통계 정보를 불러오는 기능을 구현했다.
해당 부분에서 예상하지 못한 문제가 발생했다.
정리해보면, 다음과 같은 증상이 있었다.
/stats/undefined로 요청이 나간다./stats/[code] 라우트가 정상적으로 호출되지만, 실제 코드 값이 전달되지 않는다.Error: Route "/stats/[code]" used `params.code`.
`params` is a Promise and must be unwrapped with `await` or `React.use()`
이 문제의 근본 원인은 Next.js App Router의 params 전달 방식 때문이다.
Next.js 13 이후 App Router를 사용할 경우, 서버 컴포넌트에서 dynamic route의 params가 가끔 Promise 형태로 전달된다.
로컬 환경에서는 Promise가 아닌 일반 객체처럼 보이기 때문에 문제를 알아채기 어렵다.
기존에 사용했던 코드:
export default async function StatsPage({ params }) {
const { code } = params; // 여기서 문제 발생
}
배포 후 콘솔을 찍어보면 다음과 같이 나온다.
params = Promise { { code: 'qSmO2J' }, ... }
즉, 구조분해 할당으로 바로 값에 접근할 수 없기 때문에 code가 undefined가 되고, API 요청 역시 /stats/undefined로 나가게 된다.
문제 해결은 간단하다.
params 자체가 Promise이므로, 먼저 기다린 뒤 값을 꺼내야 한다.
수정된 코드:
export default async function StatsPage({ params }: { params: Promise<{ code: string }> }) {
const { code } = await params;
const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/stats/${code}`, {
cache: "no-store",
});
if (!res.ok) {
return <div>Stats not found for {code}</div>;
}
const data = await res.json();
return <StatsView code={code} data={data} />;
}
이렇게 수정한 뒤 다시 배포하니 문제는 바로 해결되었다.
더 이상 undefined가 전달되지 않고, API에서 받은 통계 정보가 정상적으로 렌더링된다.
처음에는 API URL 문제나 환경 변수 설정 오류를 의심했지만, 원인은 Next.js가 넘겨주는 params의 형태였다.
문제가 조금 돌아가는 듯 보였지만, 배포 환경에서 콘솔을 찍어보고 값을 직접 확인하면서 원인을 정확히 잡을 수 있었다.
동일한 구조로 Dynamic Route를 사용하는 경우라면, 서버 컴포넌트에서 await params를 적용하는 것만으로도 비슷한 문제를 예방할 수 있다.