티스토리 뷰

우선 간단히 넥스트 12버전과 13버전을 비교하면 아래와 같다.

Next 12ver

페이지 단위 렌더링 방식 규정 => 13버전보다 구성이 심플할 수 있으나 효율성이 떨어질 수 있음

Next 13ver

컴포넌트 단위 렌더링 방식 규정 => 12버전보다 구성하는 것이 복잡할 수 있으나 어플리케이션 효율성이 높음

  • 리액트 18버전부터 Server Component가 도입되면서 페이지 내에 2가지 컴포넌트가 믹스되어 구성될 수 있음(클라이언트 & 서버 컴포넌트) 

서버 컴포넌트(Server Component)

app 폴더 내부에 있는 컴포넌트들은 기본적으로 서버 컴포넌트(서버에서 실행되는 컴포넌트)이다.
  • 서버 컴포넌트는 말 그대로 서버에서 실행되는 컴포넌트 이기 때문에 이 컴포넌트는 브라우저에서 그려지는 것이 아니라 이미 서버에서 실행되어 만들어진 HTML 형태로 브라우저에 도착하게 된다. (서버 컴포넌트는 당연히 서버에서 실행되는 것이겠죠?)
  • 즉, 서버 컴포넌트에서는 web API를 사용할 수 없으며 대신 node API를 활용할 수 있게 된다.
  • 서버 컴포넌트는 서버에서 빌드 될 때 실행되는 컴포넌트이다. 즉, 서버에서 처리가 되는 컴포넌트이기 때문에 브라우저에 보내줄 게 없다. 특히, 로직 코드를 클라이언트에 보내줄 필요가 없으므로 최종 번들 코드가 작아진다.
  • 서버 컴포넌트에서는 입출력이나 DB 작업, 파일 읽어오기 등이 가능하다.
  • 아주아주 당연하게도 서버 컴포넌트이기 때문에 브라우저 관련된 작업인 상태관리, 사이드이펙트 처리 등.. 이 불가능하다. e.g.) setState 로 state값을 바꾸는 등의 행위

서버 컴포넌트에서 클라이언트 훅을 사용하면 컴파일 에러를 발생시킨다.

아주 친절하게도 아래와 같은 에러 메세지를 콘솔에 찍어준다.

You're importing a component that needs useState.
It only works in a Client Component but none of its parents are marked with "use client",
so they're Server Components by default.
Learn more: https://nextjs.org/docs/getting-started/react-essentials

node API 공식 페이지 ^ _ ^ / 👨‍🌾

 

Q. 서버 컴포넌트인지 어떻게 확인하나요?

A. console.log("나는 어디서 출력되나요?"); 를 컴포넌트 내부에서 실행시켜보면 된다.

클라이언트 컴포넌트라면 브라우저 콘솔에 표시가 될 것이고 아니라면 내 terminal에 결과가 보일 것이다.


클라이언트 컴포넌트(Client Component)

✅ Next 13에서 use clinet 키워드로 만들어진 클라이언트 컴포넌트는 구분을 위해서 app 폴더 하위 보다는 그 바로 상위인 src > components 폴더에 위치시키는 게 좋다.( app 폴더의 기본 컴포넌트는 서버 컴포넌트들이니까)

 

클라이언트 컴포넌트는 무조건 CSR이 아니다

클라이언트 컴포넌트의 모든 소스코드들이 전부 클라이언트로 넘겨져서 CSR되는 것은 아니다. 

 

아래는 빌드 명령 후, 진행 과정을 담은 log들이다.

$ next build
- info Creating an optimized production build
- info Compiled successfully
- info Linting and checking validity of types  
- info Collecting page data  
[==  ] - info Generating static pages (14/22)여기는 서버단이야
DESKTOP-MAGSM8E
[=== ] - info Generating static pages (20/22)여기는 클라이언트야!
여기는 서버단이야
DESKTOP-MAGSM8E
- info Generating static pages (22/22)
- info Finalizing page optimization
  • static pages를 만들면서 “여기는 클라이언트야” 를 출력하는 것을 알 수 있는데 이는 내가 만든 클라이언트 컴포넌트에 console.log(”여기는 클라이언트야!”)를 적어놨기 때문이다. 즉, 클라이언트 컴포넌트가 HTML을 만들 때, 서버단에서 부분적으로 static하게 만들어진다는 소리이다.

클라이언트 컴포넌트와 하이드레이션

CSR은 페이지를 로드할 때, preview 컨텐츠에 포함되지 않아야 하는 것이 맞는데 막상 클라이언트 컴포넌트가 포함된 페이지를 로드하면 preview에 클라이언트 컴포넌트의 모습을 확인할 수 있다.

이미지의 파란 박스 부분이 클라이언트 컴포넌트

  • localhost 의 기본 index.html의 뼈대에 static한 모습으로 포함되어 있다.(Counter.tsx는 클라이언트 컴포넌트이다)

💡 넥스트는 클라이언트 컴포넌트를 모두를 클라이언트에서 처리하게 두는 것이 아니라 그 중에서 미리 만들어둘 수 있는 부분을 따로 추출하여 HTML로 처리해놓는다. 이렇게되면 이벤트 처리 관련이나 리액트 관련 js 파일만 클라이언트로 전송하면 되기 때문에 번들 사이즈가 감소하는 효과가 있다. 즉, 넥스트가 알아서 컴포넌트를 최적화하는 것이다.

 

⇒ 이처럼 미리 만들어둔 html에 이벤트 처리 등 브라우저에서 처리해야하는 로직을 서버에서 받아 ui에 적용하여 인터랙티브해지면 그때 비로소 리액트 컴포넌트가 된다. 이 과정을 넥스트에서 하이드레이션이라고 한다.

 

한줄 정리: 클라이언트 컴포넌트는 서버단에서 프리렌더된 뒤, 클라이언트에서 하이드레이트되는 것이다.

 

 

 

댓글