개발 기록 남기기✍️

[Next.js] 서버 컴포넌트와 클라이언트 컴포넌트 본문

Front-End/Next.js

[Next.js] 서버 컴포넌트와 클라이언트 컴포넌트

너해동물원 2023. 6. 12. 12:43

Next.js 13버전을 사용하면서 Server Component와 Client Component의 존재에 대해서 알게 되었는데, SSR, CSR 등과의 지식이 섞이니까 헷갈린다..! 파이널 프로젝트 시작 전 확실히 짚고 넘어가보자.🏃‍♀️


📌 클라이언트 컴포넌트란?

클라이언트 사이드 컴포넌트는 클라이언트(브라우저)에서 렌더되고 fetch되는 컴포넌트이다. 클라이언트 컴포넌트는 브라우저의 자바스크립트 번들을 포함하고 있는 일반적인 리액트 컴포넌트이다.

 

클라이언트 컴포넌트는 다음과 같은 특징을 갖는다.

  • 클라이언트 컴포넌트는 onClick 같은 상호작용성(인터랙션)을 포함한다.
  • 클라이언트 컴포넌트는 클라이언트라고 불리는 브라우저에서 렌더된다.
  • 클라이언트 컴포넌트는 "use client"라고 선언함으로써 클라이언트 컴포넌트인걸 나타낸다.
  • 만약 useState, useEffect같은 리액트 lifecycle hooks들을 사용할 계획이 있다면, 클라이언트 컴포넌트에서 사용해야 한다.

 

 

📌 서버 컴포넌트란?

리액트 서버 컴포넌트들은 서버에서 렌더되고 요청되는 컴포넌트들이다. 따라서 유저의 인터랙션을 제공하지 않는다.

 

서버 컴포넌트는 다음과 같은 특징을 갖는다.

  • 서버 컴포넌트는 onClick 같은 상호작용성(인터랙션)을 포함하지 않는다.
  • fallback과 함수는 props로 전달될 수 없다.
  • 서버 컴포넌트는 상호작용하지 않으며, React State가 필요가 없다.
  • 서버 컴포넌트는 리액트 lifecycle hooks를 사용하지 않는다.
  • 예시) 데이터베이스, 파일 시스템에 기반한 작업, 상호작용성이 없는 컴포넌트

기본적으로 Next.js 13버전에서 컴포넌트들은 서버 컴포넌트이다.

 

 

🤨 그래서 서버 컴포넌트의 이점이 뭔데?

  • 서버 컴포넌트는 번들에 포함되지 않기 때문에 브라우저로 가는 번들 사이즈가 현저하게 작아진다.
  • 서버에서만 사용되는 패키지 모듈들은 서버에서만 유지하면 된다.
  • API 형식으로 불러올 필요 없이, 파일시스템, DB 등에 편하게 접근할 수 있다. 물론 클라이언트 단에서 api 를 통해 패치하는 방식도 가능하다.
  • 렌더링을 함과 동시에 data를 불러오기 때문에, 렌더링 자체가 데이터를 가져오기를 시작하는 시간에 영향을 주지 않는다. 

 

😳 서버 컴포넌트와 SSR의 차이점은 뭐야?

서버 컴포넌트와 서버 사이드 렌더링은 서버에서 렌더링 된다는 유사점이 있지만 해결하고자 하는 문제점이 다르다.

 

서버 컴포넌트와 SSR은 다음과 같은 차이점이 있다.

  • 서버 컴포넌트의 코드는 클라이언트로 전달되지 않는다. 하지만 서버 사이드 렌더링의 모든 컴포넌트의 코드는 자바스크립트 번들에 포함되어 클라이언트로 전송된다.
  • 서버 컴포넌트는 페이지 레벨에 상관없이 모든 컴포넌트에서 서버에 접근 가능하다.
  • 서버 컴포넌트는 클라이언트 상태를 유지하며 refetch 될 수 있다. 서버 컴포넌트는 HTML이 아닌 특별한 형태로 컴포넌트를 전달하기 때문에 필요한 경우 포커스, 인풋 입력값 같은 클라이언트 상태를 유지하며 여러 번 데이터를 가져오고 리렌더링하여 전달할 수 있다. 하지만 SSR의 경우 HTML로 전달되기 때문에 새로운 refetch가 필요한 경우 HTML 전체를 리렌더링 해야 하며 이로 인해 클라이언트 상태를 유지할 수 없다.
  • 리액트 서버 컴포넌트들은 각각의 컴포넌트마다 클라이언트 컴포넌트로 렌더할 것인지 서버 컴포넌트로 렌더할 것인지 선택하는 반면, 서버사이드 렌더링은 페이지 당, 해당 페이지 자체를 서버사이드 렌더링을 하도록 한다.

 

서버 컴포넌트는 서버 사이드 렌더링 대체가 아닌 보완의 수단으로 사용할 수 있다. 서버 사이드 렌더링으로 초기 HTML 페이지를 빠르게 보여주고, 서버 컴포넌트로는 클라이언트로 전송되는 자바스크립트 번들 사이즈를 감소시킨다면 사용자에게 기존보다 훨씬 빠르게 인터랙팅한 페이지를 제공할 수 있을 것이다.

 

📍 서버 컴포넌트에서 클라이언트 컴포넌트로 props 전달하기

💡 Serialization(직렬화)
object(객체) 또는 data structure가 네트워크 또는 스토리지를 통한 전송에 적합한 형식으로 변환되는 프로세스를 말한다. 
예를 들어, JavaScript에서 JSON.stringify()를 통해서 객체를 JSON string으로 serialize 할 수 있다.

 

서버 컴포넌트에서 클라이언트 컴포넌트로 전달되는 props 중 functions, Dates 등과 같은 value들은 클라이언트 컴포넌트로 바로 직접적으로 넘겨줄 수 없다. 직렬화를 거쳐서 전달해줘야 한다.

 

 

📌 클라이언트 컴포넌트 vs 서버 컴포넌트

사용 예시 서버 컴포넌트 클라이언트 컴포넌트
데이터 가져오기 ⭕️
백엔드 리소스에 직접 접근 ⭕️
서버에 민감한 정보 유지하기(액세스 토큰, API keys 등) ⭕️
서버에 큰 의존성 유지 / 클라이언트 사이드 JavaScript 감소 ⭕️
상호작용성과 이벤트 리스너 추가(onClick 등) ⭕️
상태와 생명 주기 훅 사용(useState, useEffect 등) ⭕️
browser-only API 사용 ⭕️
state, effects, browser-only APIs에 의존하는 커스텀 훅 ⭕️
리액트 클래스 컴포넌트 사용 ⭕️

'Front-End > Next.js' 카테고리의 다른 글

[Next.js] 렌더링 기법 (CSR, SSR, SSG, ISR)  (0) 2023.05.24