chorock.page
소개글시리즈프로젝트
© 2026 chorock.page
← 목록으로
Next.js 기초 - App Router · 3/11
← 이전 글다음 글 →
Next.jsweb

App Router (3) - React Server Component

2026.09.23 · 4분 읽기 · 조회 0

목차
React Server ComponentPage Router 에서의 문제구현주의사항1. 서버 컴포넌트에는 브라우저에서 실행될 코드가 포함되면 안된다2. 클라이언트 컴포넌트는 클라이언트에서만 실행되지 않는다3. 클라이언트 컴포넌트에서 서버 컴포넌트를 import 할 수 없다4. 서버 컴포넌트에서 클라이언트 컴포넌트에게 직렬화 되지 않는 Props는 전달 불가하다.

React Server Component

React 18버전 부터 새롭게 추가된 새로운 유형의 컴포넌트이다.
브라우저에서 실행되지 않고, 오직 서버측에서만 실행된다.

Page Router 에서의 문제

페이지 라우터에서는 하이드레이션을 위해 JS Bundle을 내려주어야 했다.

페이지의 컴포넌트에는 상호작용이 있는 컴포넌트와 없는 컴포넌트들이 존재한다.

Page Router는 이와 상관없이 모든 컴포넌트들을 JS Bundle에 담아서 브라우저에 보내준다. 때문에 번들의 용량이 커지고, 하이드레이션 속도도 늦어진다는 문제가 있다.

App Router는 JS Bundle에서 상호작용이 없는 컴포넌트들을 JS Bundle에 포함하지 않고 내려준다.
그 결과 하이드레이션 속도가 빨라지고 TTI도 개선된다. 이때, JS Bundle에 포함되지 않고, 서버 측에서만 딱 한 번 실행되는 컴포넌트들을 React Server Component라고 한다.

이와 반대로 JS Bundle에 포함되는 컴포넌트는 Client Component가 된다.
Next.js 공식 문서에서는 페이지의 대부분을 서버 컴포넌트로 구성하고, 클라이언트 컴포넌트는 꼭 필요한 경우에만 사용할 것을 권장한다.

구현

App Router에서는 기본적으로 모든 컴포넌트가 서버 컴포넌트다.

export default function Home(){
  console.log("출력")
 
  return (내용)
}

때문에 이렇게 콘솔을 찍어도 브라우저에는 노출되지 않고, 서버 터미널에만 찍히게 된다.

export default function Home() {
  useEffect(() => {}, []);
 
  return <div></div>;
}

useEffect와 같은 브라우저에서만 실행할 수 있는 훅들을 서버 컴포넌트 내부에 적을 경우 에러가 발생한다. 이는 클라이언트 컴포넌트에서만 사용할 수 있다.

클라이언트 컴포넌트로 바꾸고 싶으면 페이지코드의 제일 위에 "use client"를 추가하면 된다.

"use client";
export default function Home() {
  useEffect(() => {}, []);
 
  return <div></div>;
}

이렇게 기재하면 해당 컴포넌트는 클라이언트 컴포넌트가 된다. 클라이언트 컴포넌트를 설정하는 기준은 명확하다.

상호작용이 필요하면 클라이언트 컴포넌트로 만들면 된다.

주의사항

1. 서버 컴포넌트에는 브라우저에서 실행될 코드가 포함되면 안된다

export default function Home() {
  // const [state, setState] = useState("");  
  // useEffect(()=>{});
 
  return (
    // <div
    //   onClick={()=>{}}>
    // </div>
  )
}

서버 컴포넌트는 서버 측에서만 실행되는 컴포넌트이기 때문에 브라우저에서는 실행되지 않는다.
때문에 훅, 이벤트 핸들러 등은 서버 컴포넌트에서 사용할 수 없다.
브라우저에서 실행되는 기능을 담고 있는 라이브러리 역시 사용할 수 없다.

2. 클라이언트 컴포넌트는 클라이언트에서만 실행되지 않는다

클라이언트 컴포넌트는 서버에서 한 번, 브라우저에서 한 번 총 두 번 실행된다.

"use client"
 
export default function Home(){
  console.log("출력")
  return ()
}

때문에 다음과 같이 입력하여도 콘솔은 서버 터미널에서 한 번, 브라우저 콘솔에서 한 번 실행된다.

3. 클라이언트 컴포넌트에서 서버 컴포넌트를 import 할 수 없다

"use client";
 
import ServerComponent from "./server-component.tsx";
 
export default function ClientComponent(){
  return <ServerClient/>;
}

다음과 같이 클라이언트 컴포넌트가 서버 컴포넌트를 임포트하면 안 된다.

서버 측에서 실행될 때는 괜찮지만, 브라우저 측에서 실행될 때는 서버 컴포넌트가 없기 때문에 없는 코드를 import 하게 되는데,
이 때 Next.js는 자동으로 서버 컴포넌트를 클라이언트 컴포넌트로 변경한다.

불필요한 클라이언트 컴포넌트가 늘어나는 것은 좋지 않으므로, 클라이언트 컴포넌트에서 서버 컴포넌트를 import 하는 것은 지양해야 한다. 불가피하게 해야하는 상황이면

export default function ClientComponent(
  children : {children : ReactNode}
){
  return <div>{children}</div>
}

다음과 같이 클라이언트 컴포넌트가 서버 컴포넌트를 {children}으로 감싸는 방식을 사용하는게 좋다.

<ClientComponent>
  <ServerComponent/>
</ClientComponent>

이렇게 하면 클라이언트 컴포넌트로 자동으로 바뀌지 않는다.

4. 서버 컴포넌트에서 클라이언트 컴포넌트에게 직렬화 되지 않는 Props는 전달 불가하다.

직렬화 (Serialization)

객체, 배열 클래스 등 복잡한 구조 데이터를
네트워크 상으로 전송하기 위해 단순한 형태(문자열, Byte)로 변환하는 것

JS의 함수는 직렬화가 불가능하다. 때문에 서버 컴포넌트 -> 클라이언트 컴포넌트 로 전달되는 Props가 될 수 없다.

사전 렌더링 과정에서 서버 컴포넌트는 먼저 RSC Payload 라는 형태로 직렬화가 된다.
그 후 클라이언트 컴포넌트도 직렬화 되어 payload와 합쳐지는데, 이 때 props 에서 직렬화되지 않는 값이 있으면 당연히 오류가 발생한다.

초록
초록

앱과 웹을 만들고, 직접 운영하며 기록합니다.

댓글

giscus로 동작하며 GitHub Discussions에 저장됩니다.

관련 글

Next.js 기초 - App RouterNext.jsweb

App Router (11) - 서버 액션 (Server Action)

2026.09.29·2분 읽기·조회 0
Next.js 기초 - App RouterNext.jsweb

App Router (10) - 우아하게 에러 핸들링하기 (error.tsx)

2026.09.28·3분 읽기·조회 0
Next.js 기초 - App RouterNext.jsweb

App Router (9) - 스트리밍

2026.09.28·3분 읽기·조회 0

목차

React Server ComponentPage Router 에서의 문제구현주의사항1. 서버 컴포넌트에는 브라우저에서 실행될 코드가 포함되면 안된다2. 클라이언트 컴포넌트는 클라이언트에서만 실행되지 않는다3. 클라이언트 컴포넌트에서 서버 컴포넌트를 import 할 수 없다4. 서버 컴포넌트에서 클라이언트 컴포넌트에게 직렬화 되지 않는 Props는 전달 불가하다.