React는 서버에서 렌더링할 수 있는 컴포넌트인 RSC를 제공함으로써
원하는 곳에서 컴포넌트를 렌더링할 수 있는 선택지를 제공한다.
기존의 Server Side Rendering(SSR)과 다른 점을 간단하게 정리하자면,
SSR(서버 사이드 렌더링)은 서버에서 페이지 단위로 정적인 리소스를 생성하지만
RSC(리액트 서버 컴포넌트)는 컴포넌트 단위로 정적인 리소스를 생성할 수 있다는 점이다.
여기서 RSC의 가장 큰 장점이 나온다.
클라이언트로 내려보내는 JavaScript 번들 크기를 줄일 수 있게 된다.
뿐만 아니라, 데이터베이스와 가까운 곳에서 데이터를 조회하기 때문에 속도도 더 빨라질 수 있다.
이러한 장점 덕분에 Next.js에서는 RSC를 기본 컴포넌트 렌더링 방식으로 채택하고 있다.
브라우저 API를 사용하거나 useState, useEffect 등의 훅을 이용해야 하는 경우,
클라이언트 컴포넌트를 사용해야 한다.
이럴 땐 파일의 가장 첫 줄에 ‘use client’라고 명시해야 한다.
'use client'
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p> You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
)
}
아래의 표는 서버 컴포넌트와 클라이언트 컴포넌트를 사용해야 하는 경우를 구분 지은 것이다.
원하는 기능 | 서버 컴포넌트 | 클라이언트 컴포넌트 |
---|---|---|
데이터 가져오기 | O | |
백엔드 리소스에 직접 접근하기 | O | |
민감한 정보를 서버에 보관할 때 (엑세스 토큰, API 키 등) | O | |
JavaScript 리소스 줄이기 | O | |
상호작용 및 이벤트 리스너(onClick, onChange 등) 사용하기 | O | |
상태 및 생애 주기 관리(useState, useEffect 등) | O | |
브라우저 API 사용하기 | O | |
React 클래스 컴포넌트 사용하기 | O |
Next.js에서는 서버 컴포넌트에서 클라이언트 컴포넌트를 불러올 수 있다.
반면, 클라이언트 컴포넌트에서 서버 컴포넌트를 불러오는 패턴은 지원되지 않는다.
(단, 직접 불러올 수는 없지만 자식 요소로 전달할 수는 있다.)
'use client'
// 클라이언트 컴포넌트에서 서버 컴포넌트를 불러오기 할 수 없다.
import ExampleServerComponent from './example-server-component'; // X
import { useState } from 'react';
export default function ExampleClientComponent({
children, // 하지만, 서버 컴포넌트를 자식 요소로 전달할 수 있다.
} : {
children: React.ReactNode
}) {
const [count, setCount] = useState(0)
return (
<>
<button onClick={() => setCount(count + 1)}{count}</button>
<ExampleServerComponent /> /* X */
{children}
</>
)
}