Skip to main content

Command Palette

Search for a command to run...

[React] Server component (RSC)

Updated
3 min read

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 componentserver 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