Next.js 15 App Router에서 서버 컴포넌트와 클라이언트 컴포넌트 경계 설정 팁
Next.js 15로 프로젝트를 리팩토링 중인데, 서버 컴포넌트와 클라이언트 컴포넌트의 경계를 어디에 둬야 할지 고민입니다.
예를 들어, 데이터 fetching은 서버에서 하고 interaction(버튼 클릭, form submit)은 클라이언트에서 처리해야 하는데, 이걸 한 페이지 안에서 어떻게 구성하는 게 best practice일까요?
현재는 큰 서버 컴포넌트 안에 필요한 부분만 클라이언트 컴포넌트로 분리해서 import하고 있는데, props drilling이 좀 심해지네요. 아니면 아예 레이아웃 단위로 분리하는 게 나을까요? 경험 있으신 분들 조언 부탁드립니다.
3 개의 답변
저도 비슷한 고민을 했었는데, 저는 데이터 fetching이 필요한 부분은 서버 컴포넌트로 두고, 상호작용이 필요한 UI 조각만 클라이언트 컴포넌트로 분리하는 방식을 사용합니다. Props drilling 문제는 React Context나 서버 액션(Server Actions)을 활용하면 많이 완화됩니다. 예를 들어, 버튼 클릭 시 서버 액션을 호출하면 props 전달 없이도 처리가 가능해져요. 레이아웃 단위 분리도 좋지만, 너무 크게 나누면 오히려 복잡해질 수 있으니 작은 단위로 쪼개는 걸 추천합니다.
저는 개인적으로 '서버 컴포넌트를 컨테이너로, 클라이언트 컴포넌트를 프레젠테이셔널로' 접근합니다. 서버에서 데이터를 받아 클라이언트 컴포넌트에 children으로 넘기는 패턴을 쓰면 props drilling이 줄어들어요. 예를 들어, ServerComponent에서 fetch 후 ClientComponent를 감싸서 {children}으로 렌더링하는 식이요. Next.js 15의 use 훅도 도움이 될 수 있으니 한번 찾아보세요. 레이아웃 분리는 정말 큰 단위(예: 사이드바 vs 메인 콘텐츠)에서만 사용합니다.
저도 똑같은 상황이었는데, 결국 '서버 컴포넌트는 데이터 fetching과 초기 렌더링, 클라이언트 컴포넌트는 사용자 액션'이라는 원칙으로 나누니 깔끔해졌어요. Props drilling이 심하다면, 관련 데이터를 서버 액션으로 처리하거나 zustand 같은 가벼운 상태 관리 라이브러리를 클라이언트 영역에 도입하는 것도 방법입니다. 레이아웃 단위 분리는 저도 시도했지만, 오히려 파일이 많아져서 관리가 힘들더라고요. 작은 단위로 쪼개고 서버 액션을 적극 활용해보세요!