Skip to main content

[React] Server component (RSC)

Updated 3 min readMarkdown

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

No comments yet. Be the first to comment.

More from this blog