Tweet not found
The embedded tweet could not be found…
6분
React Server Component(이하 RSC)가 무엇인지, 또 그리고 어떻게 인식하고 사용하면 좋을지에 대한 Dan Abramov의 트위터 글을 옮겨보았습니다.
이 글을 정리하고 읽으면서 RSC에 대한 멘탈 모델을 조금이라도 얻을 수 있었으면 좋겠습니다.
RSC는 React 18버전에서 소개된 새로운 형태의 컴포넌트입니다 이 컴포넌트는 서버에서만 렌더링되며, 클라이언트로 렌더링 결과물의 HTML이 특별한 구조로 전송됩니다. 사실 HTML 문서가 직접 전송되지 않고 컴포넌트 형태를 특별한 형태(serialize된 JSON Data)로 전송합니다. 그로 인해 전송 오버헤드를 줄이고 빠른 렌더링이 가능해집니다.
서버에서만 렌더링되기 때문에 클라이언트로 내려오는 JavaScript 번들 사이즈를 줄일 수 있습니다. 또한 서버에서 동작하는 컴포넌트이기 때문에, DB 접근이나 파일 시스템 접근 등의 서버 작업을 할 수 있습니다. 이로 인해 얻을 수 있는 장점이 많습니다.
렌더링에 필요한 데이터를 위해 API 호출 필요 자체가 없어진다면 어떤지 생각해보신적이 있나요? RSC는 이런 것들을 가능하게 해줍니다.
React는 클라이언트 사이드 렌더링(CSR) 라이브러리로 많이 알려져 있는데 RSC는 그와 반대되는 것 아닌가요?
CSR의 문제점은 초기 페이지 로딩 시 클라이언트에서 발생하는 렌더링 작업이기 때문에, 초기 페이지 로딩 시간이 길어지고 사용자 경험이 저하된다는 것입니다. React도 이를 해결하기 위해 서버 사이드 렌더링(SSR)을 결합하여 초기 로딩 성능을 개선하고 SEO 등을 향상시키는 기법을 찾고 있었습니다. 그 중 하나가 RSC 입니다. 기존 SSR 방식과 달리, RSC는 서버에서 렌더링된 결과물을 정적 HTML이 아닌 데이터 구조 형태로 전송됩니다. 이 데이터 구조를 받은 클라이언트는 React 애플리케이션에 빠르게 렌더링 할 수 있습니다.
RSC는 초기 페이지 로드 및 데이터 효율성에 도움이 되는 반면에 클라이언트 컴포넌트는 상호작용 및 동적 기능에 필요합니다.
따라서 RSC는 CSR과 SSR의 장점을 결합한 것으로 볼 수 있습니다. CSR에 반대되는 개념이 아니라 기존 React의 클라이언트 사이드 렌더링을 보완하는 새로운 기능입니다.
We generally recommend using an existing framework, but if you need to build your own custom framework, it is possible. Building your own RSC-compatible framework is not as easy as we’d like it to be, mainly due to the deep bundler integration needed.
- react.dev/blog
RSC 호환 프레임워크를 직접 구축하는 것은 생각만큼 쉽지 않기에 현재 React 공식문서에서는 RSC를 사용하기 위해 일반적으로 프레임워크를 사용하기를 권장합니다.(Next.js는 RSC를 가장 잘 지원하고 있는 프레임워크 중 하나입니다.)
Dan Abramov의 트위터 설명과 질문응답을 통해 RSC에 대해 더 자세히 알아보겠습니다.
The embedded tweet could not be found…
이는 서버 컴포넌트와 클라이언트 컴포넌트의 큰 차이점을 보여줍니다.
파란색 항목(서버 컴포넌트)은 서버에서만 동작하므로 DB, 파일 등을 읽을 수 있습니다.
초록색 항목(클라이언트 컴포넌트)은 클라이언트와 서버 모두에서 동작하므로 서버 전용 기능을 사용할 수 없고 리렌더링에서 실행되어야 합니다.
Remix와 비교하면, Remix에서는 loader
를 제외한 모든 것이 "초록색"(클라이언트 컴포넌트)입니다.
즉, 라우트 세그먼트 당 파란색 부분(서버 컴포넌트)은 하나만 가질 수 있고 더 아래로는 구성할 수 없습니다.
Astro와 비교하면, Astro는 파란색 부분(서버 컴포넌트)과 초록색 부분(클라이언트 컴포넌트)이 모두 존재하지만 서로 다른 언어로 작성되어 있습니다.(파란색 = Astro, 초록색 = React) 또한 페이지가 로드된 후 파란색 부분(서버 컴포넌트)를 리렌더링하는 기능(예: 네비게이션 또는 뮤테이션)이 지원되지 않습니다.
Rails(Turbolinks)와 비교하면, Rails에서 파란색 부분(서버 컴포넌트)는 refetch가 가능하지만, 다른 언어(templates)로 작성되어야 하고, 동기화되어야 하며(심지어 DB를 읽는 것도 동기화되어야 함), refetch 시에 초록색 부분(클라이언트 컴포넌트)의 상태가 손실될 수 있다고 생각합니다.
이것을 의미하는 건가요? 양쪽 모두에서 작동합니다.
<Comments>
컴포넌트를 새로고침버튼을 통해 새로고침하려면, 이것은 HTTP 요청인가요? 아니면 RSC가 서브트리를 리렌더링할 수 있나요?<Tweet />
컴포넌트를 사용하고 싶다고 가정해 보겠습니다.
그러나 일부 텍스트 위에 마우스를 올렸을 때 툴팁과 같이 클라이언트 사이드 상호작용이 발생한 후에만 사용자에게 표시하고 싶습니다.
Next.js에서는 라우트 세그먼트를 통해 이 작업이 수행된다는 것을 알고 있지만 어떻게 수행되는지 명확하지 않습니다.Dan Abramov가 RSC에 대해 조금 더 이해하기 쉽게 퀴즈를 내고 답변을 달아주는 글인데 잘 정리되어 있어서 옮겨 보았습니다.
이 중 유일한 클라이언트 컴포넌트는 <Toggle />
입니다. 상태(isOn
, 초기값 false
)를 가지고 있습니다. 그리고 <>{isOn ? children : null}</>
을 반환합니다.
setIsOn(true)
를 하면 어떻게 될까요?
<Details />
를 fetch한다.<Details />
가 즉시 나타난다.RSC Quiz 1 답변:
(2) <Details />
가 즉시 나타납니다.
모든 RSC는 서버에서 단일 패스로 실행되므로 (명시적으로 라우터 새로고침이나 네비게이션을 하지 않는 한) 앞뒤로 이동하지 않습니다.
따라서 <Toggle />
클라이언트 컴포넌트 관점에서 children
prop은 <Details />
의 렌더링 출력 입니다.
이제 isOn
이 true
라고 가정해보겠습니다. note
를 수정하고 라우터에 경로를 "새로고침"하라고 지시했습니다.
그러면 이 라우트에 대한 RSC 트리가 refetch되고 Note
서버 컴포넌트가 최신 DB 내용을 포함한 note
prop을 받습니다.
<Details />
에 새로운 콘텐츠가 표시됩니까?RSC Quiz 2 답변:
(2) 클라이언트 상태는 refetch 시에 초기화 되지 않습니다. 이것은 일반적인 React처럼 작동합니다.
같은 위치에서 같은 내용이 렌더링된다면 업데이트하는 동안에 상태가 유지됩니다.
초기화할 이유가 없습니다. 하지만 새로운 데이터는 나타납니다. <Toggle />
은 새로운 children
을 받습니다.
조금 더 꼬아보겠습니다.
위 컴포넌트 모두 서버 컴포넌트입니다.
하지만 마우스를 드래그하면 변경되는 열 너비와 같은 상태를 <Layout />
에 추가하려고 합니다.
<Layout />
을 클라이언트 컴포넌트로 만들 수 있을까요? 만약 그렇다면 드래그 시에 어떻게 될까요?
RSC Quiz 3 답변:
(3) 드래그 시에 refetch가 없습니다. 일반적으로 라우터에 요청하지 않는 한 RSC 트리는 refetch되지 않습니다.
<Layout />
컴포넌트 관점에서 보면 다음과 같습니다.
left
와 right
prop은 <Sidebar />
와 <Content />
의 렌더링 출력 이므로 디스플레이가 유지됩니다.
어떻게 <Sidebar />
와 <Content />
를 렌더링할지 말지 알 수 있을까요? JSX가 열심히 호출하고 있는걸까요?
그렇지 않습니다. 단지 <Layout />
(클라이언트에서 실행되는)을 렌더링하려고 할 때 props를 serialize하기 때문입니다.
serialize하는 동안 JSX를 발견하면 이를 실행합니다.
Next.js App Router를 사용하면서 직간접적으로 RSC를 사용하고 있습니다.
하지만 정확하게 이해하지 못하고 있었는데, 이 글을 통해 RSC에 대해 조금 더 이해할 수 있었습니다.
위 질문에도 나왔지만 React는 점점 더 복잡해지고 이해하기 어려워지고 있습니다.
하지만 이러한 부분은 React를 사용하는 개발자들이 더 쉽게 개발할 수 있도록 도와주는 것이라고 생각합니다.
마지막으로, 이 글이 여러분의 프로젝트에 RSC를 도입하는 데 도움이 되길 바랍니다.
더 많은 개발자들이 성능과 사용자 경험을 개선하는 데 활용할 수 있기를 기대합니다.
4/30/2023