Skip to main content

Command Palette

Search for a command to run...

[React] Server component (RSC)

Updated
•3 min read•View as Markdown

React.js 18 에 도입된 리액트 서버 컴포넌트는 서버에서 동작하는 리액트 컴포넌트를 의미합니다. Next가 권장하는 라우팅 방식인 app router의 기반이 되는 컴포넌트이기 때문에 app router 를 이해하기 위해서는 server component 에 대한 이해가 필요합니다.

server component

리액트는 클라이언트단만을 컴포넌트화하는 대신, server component라는 개념을 통해 서버 영역을 컴포넌트화합니다.

(출처: https://github.com/reactwg/server-components/discussions/4)

서버 컴포넌트의 등장으로 server component 에서 데이터를 직접 가져와 client component 로 데이터를 prop 하는 형식으로 server 영역과 client 영역이 구분되기 시작했습니다.

서버컴포넌트는 컴포넌트 렌더링을 클라이언트가 아닌 서버에서 수행합니다. 서버에서 동작하기 때문에 서버 사이드 데이터에 직접 접근할 수 있으며, 유저와의 상호작용을 추가할 수 없기 때문에 클라이언트 컴포넌트와 서버 컴포넌트를 적절히 사용하는 것이 중요합니다.

서버컴포넌트는 data fetching 측면에서 기존 클라이언트 컴포넌트에서 나타나는 문제점을 해결할 수 있습니다.


  1. client-server waterfall 문제 해결 : 아래처럼 컴포넌트마다 다른 데이터 fetch 를 하려고 한다는 상황을 생각해봅시다.

     function HomePage(){
         return (
             <ParentComponent>
                 <ChildrenComponentOne/>
                 <ChildrenComponentTwo/>
             <ParentComponent/>
         )
     }
    

    이 경우 부모 컴포넌트는 api 호출이 완료될때까지 렌더링되지 않고, 자식 컴포넌트들의 렌더링과 api 호출이 수행되지 않습니다.(waterfall 문제 -> 성능 저하)

    중첩되는 컴포넌트가 많아질수록 client-server api 호출은 많아질 것이고, 호출에 대한 응답이 완료될 때 까지 기다리는 waterfall 문제는 더욱 심각해집니다.

     //server component
     import dbConnect from 'db'; 
    
     async function MyPost(props) {
       const {userId} = props;
       const userData = await dbConnect.users.get(userId);
    
       return (
         <div>
           <div>{userData.post}</div>
         </div>
       );
     }
    

    다음은 server component 에서 데이터를 직접 fetch 하는 예시 코드입니다. server component 를 통해서 server-to-server로 데이터를 요청한다면 데이터 요청의 latency 를 줄일 수 있고, api 호출 없이 직접 DB 에 접근해 데이터를 가져올 수 있기 때문에 중첩되는 client-server api 호출을 제거할 수 있습니다.

  2. js 번들 사이즈 줄이기

    서버 컴포넌트는 렌더링을 서버에서 수행하기 때문에 클라이언트단의 번들 사이즈를 감소시킬 수 있습니다. (서버컴포넌트는 서버에서 수행된 결과를 전달하기 때문에 번들을 필요로하지 않음)


server component VS server side rendering

server component 와 server side rendering 개념은 혼동하기 쉬운 개념입니다. 하지만 둘은 다른 것..! (둘은 보완 개념에 가깝습니다.)

  • (Next.js 에서의 서버사이드렌더링을 기준으로) 서버사이드렌더링은 서버에서 미리 정적인 html 을 생성해주어 초기 랜딩 시 사용할 수 있도록 합니다.

  • 하지만 서버 컴포넌트는 서버 영역을 컴포넌트화한것으로, 클라이언트에서는 보이지 않도록, 서버에서만 실행되도록 하는 컴포넌트입니다. (ssr 은 코드는 js 번들에 포함되어 클라이언트로 전송됨)

client component 와 server component 적절히 사용해보기

server component 내에서 client component import -> 가능

client component 내에서 server component import -> 불가

위에서 언급한 것 처럼 서버 컴포넌트에서는 유저 인터렉션 관련 작업을 수행할 수 없습니다. 따라서 서버 컴포넌트 데이터를 그 안에서 import 한 클라이언트 컴포넌트로 props 로 전달하는 방식을 사용해야 합니다. (Next.js 는 client component 를 leaf node 로 둘 것을 권장)

이런 패턴으로 배치한 컴포넌트는

1. 모든 서버 컴포넌트 렌더링

2. 클라이언트단에서 리액트가 클라이언트 컴포넌트와 1의 결과(slot) 를 렌더링, 즉 합침

의 과정으로 동작합니다.

위에서 user 의 post 를 보여주는 예시 코드를 보여줬는데, 이와 같이 유저 인터렉션이 필수적이지 않은 상황에서는 server component 를 활용하는 것이 적절하고, 글을 작성하거나 업데이트하는 등의 상호작용이 필요한 경우에는 useState 등의 hook을 사용할 수 있는 client component 를 활용해야 합니다.

참고

https://tech.kakaopay.com/post/react-server-components/

https://velog.io/@asdf99245/Next.js-app-router-%EA%B3%B5%EC%8B%9D%EB%AC%B8%EC%84%9C-%EC%A0%95%EB%A6%AC

More from this blog

[ZSH] tree 사용하기

들어가며 큰 규모의 프로젝트를 출시한 뒤, 후일을 위해서 더 늦기 전에 파일 정리 및 문서화를 진행해야했다. 문서화 작업을 하는 중에 기왕 정리하는 거 파일 구조를 이쁘게 트리 구조로 나열하여 코멘트를 달면 나중에 보더라도 이해하기 더 쉬울 것 같았다. 어떻게 해야 간지나는 트리 구조를 만들 수 있을까 방법을 찾다보니 역시나 파일 구조를 트리로 이쁘게 출력해주는 커맨드 툴이 존재했다. tree 커맨드에 대해서 알아보고 알짜배기 내용만 정리했다....

Feb 21, 20242 min read

[Next.js] parallel routes & intercepting routes

트위터 로그인 모달창을 만들어보며 넥스트의 parallel routes 와 intercepting routes 을 학습한 내용을 정리해보았습니다. 트위터 로그인 창을 확인해봅시다. 루트 디렉토리 화면을 배경으로 i/flow/login 페이지가 동시에 표시되고 있습니다. 저는 app router 를 학습하기 전까지는 createPortal 을 사용하여 포탈 영역에 로그인 컴포넌트를 띄우는 방식을 사용했었습니다. const NoLogin =()=...

Feb 1, 20244 min read

C/C++ 이진 트리(binary tree) 개요 및 구현(1)

개요 트리는 노드들이 나무 가지처럼 연결된 비선형 계층적 자료구조이다. 하위 트리가 존재하고, 그 노드에 또 하위 트리가 존재하는 자료구조 이다. 트리의 맨 위에 있는 루트 노드가 존재한다. 우리가 알아볼 트리는 이진 트리이다. 이진 트리는 자식 노드(부모로부터 아래로 이어진 노드)가 2개 이하인 구조를 말한다. 트리의 사용 사례로는 다음과 같다 계층 적 데이터 저장(파일,폴더) 효율적인 검색 속도 힙 데이터 베이스의 인덱싱 트리에 ...

Jan 31, 20244 min read

Flutter, JavaScript

42 posts