서론
사이드 프로젝트를 진행하며 '동적 매개변수'를 가져와 사용해야 하는 일이 생겼다. 처음에는 useParams를 사용해 값을 가져왔지만 빌드를 해보니 에러가 엄청나게 떠 있었다. 에러의 이유는 useParams를 서버 컴포넌트인 page.tsx에서 사용했던 것이 문제였다.
useParams란?
useParams는 현재 페이지의 URL 파라미터 값을 가져오는 Next.js의 훅이다. 예를 들어 아래와 같은 URL 경로가 있다면 [locale]는 동적 세그먼트이다. useParams는 이 값을 가져오는 훅이다.
/app/[locale]/page.tsx
useParams는 런타임에서 URL 값을 읽기 때문에 서버 컴포넌트에서 사용한다면 브라우저의 현재 URL 정보를 직접 읽을 수 없다.
클라이언트 컴포넌트와 서버 컴포넌트
Next.js App Router 에서는 서버 컴포넌트와 클라이언트 컴포넌트가 존재한다.
먼저 Next.js 는 기본적으로 SSR을 사용한다. SSR은 서버 사이드 렌더링 즉, 서버에서 데이터를 가져오는 방법을 사용한다. 이 방법은 SPA와 반대되는 개념으로 보안성 용이, 높은 SEO, 빠른 초기 렌더링 속도 등 다양한 이점을 가지고 있다.
하지만 이로 인한 문제점도 발생한다. 서버에서 데이터를 불러오면 유저의 이벤트에 반응 할 수 없다는 점이다. Next.js 에서는 이런 문제점을 클라이언트 컴포넌트를 사용해 해결했다.
클라이언트 컴포넌트는 유저의 이벤트, 브라우저의 훅 모두 사용이 가능하다. 따라서 next.js를 사용할 때에는 컴포넌트 분리 방법을 더욱 신경써서 해야할 듯 하다.
구분 | 서버 컴포넌트 | 클라이언트 컴포넌트 |
실행 위치 | 서버(Node.js) | 브라우저 |
사용 목적 | 데이터 fetch, SEO 최적화, 초기 렌더링 | 상태 관리, 이벤트 처리, 브라우저 API 사용 등 |
선언방식 | 별도 선언 없이 기본 | 파일 상단에 'use client' 명시 |
예시 기능 | DB 쿼리, API fetch | useState, useEffect, useParams, 클릭 이벤트 등 |
브라우저 전용 훅 사용 | x | o |
에러 원인 🤔
useParams는 브라우저에서 동작하는 훅이다. 따라서 서버에서는 해당 값을 알 수가 없다. 따라서 useParams를 이용해 받은 값은 undefined가 될 것이고 이로 인한 에러가 발생했었다.
해결 방법 ✅
useParams를 사용하는 부분만 따로 클라이언트 컴포넌트로 분리하면 된다. 그 후 page.tsx에서는 이 클라이언트 컴포넌트를 <Suspense>로 감싸서 불러오면 해결할 수 있다.