서버 컴포넌트(RSC)가 다 해주는데, SWR이 아직 필요할까요?
Next.js 13, 14로 넘어오면서 App Router와
React Server Components(RSC)가 표준이 되었습니다.
이제 `fetch` API만으로도 서버에서 데이터를 가져올 수 있게 되었죠.
여기서 많은 개발자분들이 고민에 빠집니다.
"데이터 페칭은 이제 서버 컴포넌트가 다 하는데, SWR이나 React Query
같은 클라이언트 라이브러리는 버려야 하나요?"
결론부터 말씀드리면
"아니요, 오히려 둘의 시너지는 강력합니다"입니다.
오늘은 App Router 환경에서 SWR을 어떻게 배치하고 활용해야 최고의 성능을
낼 수 있는지, 그 황금 밸런스를 정리해 드립니다.
⚖️ 1. 서버 컴포넌트 vs SWR: 역할 확실히 나누기
App Router 시대에는 '언제',
'어디서' 데이터를 가져올지가 가장 중요합니다.
모든 것을 SWR로 처리하던 Pages Router 시절의 습관은 버려야 합니다.
두 기술은 경쟁 관계가 아니라 상호 보완 관계입니다.
📌 기술별 최적 사용 시나리오
| 구분 | 서버 컴포넌트 (RSC) | SWR (Client) |
|---|---|---|
| 주목적 | 초기 로딩 속도 (FCP), SEO 최적화 | 실시간 데이터 갱신, 사용자 상호작용 |
| 데이터 성격 | 블로그 글, 제품 상세 정보 등 정적인 데이터 | 좋아요 수, 댓글, 알림, 주식 차트 등 동적인 데이터 |
| 실행 위치 | 서버 (브라우저 JS 번들 포함 X) | 브라우저 (클라이언트) |
즉, 뼈대와 핵심 콘텐츠는 서버 컴포넌트로 그리고, 살아서 움직여야 하는 부분만 SWR에게 맡기는 전략이 필요합니다.
🛠️ 2. App Router에서 SWR 제대로 구현하기
SWR은 Hooks 기반이므로 오직
클라이언트 컴포넌트(`'use client'`) 내부에서만 사용할 수
있습니다.
하지만 App Router의 기본은 서버 컴포넌트입니다. 여기서 충돌이 발생하죠.
이를 해결하기 위한 두 가지 핵심 패턴이 있습니다.
서버 컴포넌트 파일(`page.tsx`, `layout.tsx`)에 직접 `useSWR`을 작성하면 에러가 발생합니다.
반드시 별도의 클라이언트 컴포넌트로 분리하거나, `'use client'` 지시어를 상단에 명시해야 합니다.
Pattern A: 격리된 클라이언트 컴포넌트 (Recommended)
데이터 갱신이 필요한 부분만 작은 컴포넌트로 쪼개고, 그 안에서 SWR을
사용하는 방식입니다.
가장 Next.js스러운 방법입니다.
'use client';
import useSWR from 'swr';
export default function LiveUserCount() {
const { data } = useSWR('/api/user', fetcher);
if (!data) return <div>Loading...</div>;
return <div>접속자: {data.count}</div>;
}
Pattern B: SWRConfig Provider 래핑
전역 설정(fetcher 등)을 공유하고 싶다면, `SWRConfig`를 제공하는 별도의 Provider 컴포넌트를 만들어 `layout.tsx`를 감싸야 합니다.
🚀 3. 궁극의 패턴: 서버 페칭 + SWR Hydration
이 글의 핵심입니다. 서버 컴포넌트의 SEO 장점과 SWR의
실시간성을 모두 잡는 방법입니다.
Next.js 공식 문서에서도 권장하는
'데이터 미리 채우기(Pre-fetching)' 전략입니다.
🎯 작동 원리 3단계
- Step 1 (Server): `page.tsx`(서버 컴포넌트)에서 `fetch`로 데이터를 미리 가져옵니다.
- Step 2 (Pass): 가져온 데이터를 클라이언트 컴포넌트의 props로 넘기거나, `SWRConfig`의 `fallback` 옵션에 주입합니다.
- Step 3 (Client): SWR은 초기값으로 전달받은 데이터를 즉시 화면에 보여주고(로딩 없음!), 백그라운드에서 최신 데이터를 다시 확인(Revalidation)합니다.
이 방식을 사용하면 사용자는
로딩 스피너를 볼 필요가 없으며, 검색 엔진은
완성된 HTML을 읽어갈 수 있습니다.
동시에 페이지에 머무르는 동안 데이터는 SWR에 의해
항상 최신 상태로 유지됩니다.
🎓 도구에 갇히지 마세요
App Router가 나왔다고 해서 기존의 훌륭한 라이브러리들이 쓸모없어지는 것은
아닙니다.
오히려 Next.js의 서버 능력과 SWR의 클라이언트 능력을 조합했을 때, 사용자
경험(UX)은 극대화됩니다.
- 정적 데이터: 과감하게 SWR을 제거하고 서버 컴포넌트(`fetch`)로 전환하세요.
- 동적 데이터: 클라이언트 컴포넌트 내부에서 `useSWR`을 사용하세요.
- 하이브리드: 초기 데이터는 서버에서, 갱신은 SWR로 처리하는 Fallback 패턴을 적용해보세요.
지금 바로 여러분의 프로젝트에서 'use client'가 남발된 곳은 없는지, 혹은
불필요하게 서버 부하를 주고 있는 곳은 없는지 점검해보시기 바랍니다.

댓글 쓰기