React Server Components 도입 검토 중 마주친 혼란

배경

Next.js 13의 App Router가 stable이 되면서 프로젝트에 도입을 검토하고 있다. React Server Components(RSC)가 핵심인데, 기존 CSR/SSR 개념과 달라서 혼란스러운 부분이 많았다.

마주친 문제

1. 'use client' 지시어의 위치

처음엔 이벤트 핸들러가 있는 컴포넌트에만 붙이면 된다고 생각했다. 하지만 Context Provider, useState 등 React hooks를 사용하는 모든 파일 최상단에 필요했다.

// app/components/Counter.jsx
'use client';

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
}

2. Server Component에서 Client Component로 props 전달

함수를 props로 넘길 수 없다는 제약이 있었다. Serializable한 데이터만 가능하다.

// ❌ 불가능
<ClientComponent onUpdate={() => console.log('update')} />

// ✅ 가능
<ClientComponent data={serializedData} />

3. async/await를 컴포넌트에서 직접 사용

Server Component는 async 함수가 될 수 있다는 게 신선했다.

// app/posts/page.jsx
export default async function PostsPage() {
  const posts = await fetchPosts(); // API 호출
  return <PostList posts={posts} />;
}

기존엔 useEffect + useState 조합이었는데, 이제 서버에서 데이터 페칭이 가능해졌다.

결론

RSC는 패러다임이 꽤 다르다. 클라이언트/서버 경계를 명확히 이해해야 하고, 기존 컴포넌트를 그대로 옮기기 어렵다. 당분간은 기존 Pages Router와 병행하며 점진적으로 마이그레이션하는 게 현실적일 것 같다.

레퍼런스 문서가 아직 부족해서 시행착오가 많았다. 프로덕션 적용은 좀 더 지켜본 후 결정할 예정이다.