# [React] Server component (RSC)

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

### server component

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

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706529083470/87f56227-c038-47b5-b45a-4de2dd317069.png align="center")

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

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

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

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

---

1. **client-server waterfall** 문제 해결 : 아래처럼 컴포넌트마다 다른 데이터 fetch 를 하려고 한다는 상황을 생각해봅시다.
    
    ```javascript
    function HomePage(){
        return (
            <ParentComponent>
                <ChildrenComponentOne/>
                <ChildrenComponentTwo/>
            <ParentComponent/>
        )
    }
    ```
    
    이 경우 부모 컴포넌트는 api 호출이 완료될때까지 렌더링되지 않고, 자식 컴포넌트들의 렌더링과 api 호출이 수행되지 않습니다.(waterfall 문제 -&gt; 성능 저하)
    
    중첩되는 컴포넌트가 많아질수록 client-server api 호출은 많아질 것이고, 호출에 대한 응답이 완료될 때 까지 기다리는 waterfall 문제는 더욱 심각해집니다.
    
    ```js
    //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 -&gt; 가능
> 
> client component 내에서 server component import -&gt; 불가

위에서 언급한 것 처럼 서버 컴포넌트에서는 유저 인터렉션 관련 작업을 수행할 수 없습니다. 따라서 서버 컴포넌트 데이터를 그 안에서 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://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](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)
