학습 Next.js - Day 13 / React Server Component 개념 및 사용법,

이유승·2024년 10월 9일

Next.js 학습

목록 보기
14/27



1. React Server Component

  • Next.js - App Router의 가장 핵심적인 개념 중 하나.

  • React.js 18버전에서 추가된, 새로운 유형의 컴포넌트.

  • 브라우저가 아닌, 서버에서만 실행되는 컴포넌트.

  • 프론트엔드 라이브러리에서 왜 서버에서만 실행되는 컴포넌트가 있을까?
    -> 이를 이해하기 위해서는 우선, 왜 Server Component라는 개념이 탄생했는지를 돌아봐야 한다.



Server Component 이전 시대

  • Page Router 버전의 Next.js의 이야기.

  • 우선 용량이 큰 JS 파트를 제외한 HTML, CSS 파트만 렌더링해서 사용자에게 전달. 화면을 빠르게 보여줄 수 있도록 하고, 나중에 JS Bundle을 전달하여 Hydration수화를 통해 상호작용이 가능한 완전한 페이지로 거듭난다.

  • 그런데 이 JS Bundle에는 상호작용이 포함되지 않은, Hydration수화를 거치지 않아도 되는 것들이 모두 포함될 수 밖에 없었다.
    -> 컴포넌트를 나누어서 보내자니, 무엇을 기준으로 컴포넌트를 구분할지부터 어떻게 구분하겠냐는 문제까지 있다.

  • 이 문제를 해결하기 위해서는, Hydration수화가 필요한 컴포넌트와 그렇지 않은 컴포넌트를 구분할 수 있어야 한다.
    -> Hydration수화가 필요하지 않은 컴포넌트들은 Next 서버에서 UI 렌더링을 위해서 1번만 실행하고, 그 이후에는 실행하지 않도록 구분해주어야 한다.
    -> 이를 위해 개발된 것이 Server Component.

Hydration수화가 필요한 컴포넌트 -> 클라이언트 컴포넌트
=> 사전 렌더링 과정에서 1번 실행.
=> Hydration수화 과정에서 1번 실행.

Hydration수화가 필요하지 않은 컴포넌트 -> 서버 컴포넌트
=> 사전 렌더링 과정에서 1번 실행.

  • 렌더링된 HTML들이 넘어갈 때는 서버 컴포넌트가 같이 넘어간다.

  • JS Bundle이 넘어갈 때에는 클라이언트 컴포넌트만 넘어간다.
    -> 이로써 번들 용량이 줄어들고, 데이터를 전달하는 시간과 자원이 줄어들어 FCP와 TTI를 모두 효율화할 수 있다.

  • 따라서 Next.js의 개발 원칙은 페이지는 기본적으로 서버 컴포넌트로 구성하고, 필요한 경우에만 클라이언트 컴포넌트를 사용하는 것.



2. Server Component의 구분

  • Server Component는 개발자가 명시적으로 구분할 필요가 없다. Next.js의 컴포넌트는 따로 설정하지 않으면, 기본적으로 Server Component로 간주되기 때문.

  • Server Component의 값들은 클라이언트로 넘어가지 않는다. 비밀키를 작성한다고 해도, 이는 Next.js 서버에서만 남아있고 브라우저로 넘어가지 않는다.
    -> 반대로 브라우저에서만 수행 가능한 작업들은 Server Component에서 수행할 수 없다.
    -> 대표적으로 useEffect와 같은 Hooks들. Server Component에서 수행이 불가능한 작업이기에 에러가 발생한다.



Cilent Component는 어떻게 설정하는가?

"use client";

import { useState } from "react";

export default function Searchbar() {

	(...)
    
  return (
		(...)
  );
}
  • 컴포넌트 최상단에 "use client"라는 문자열을 입력하면, 해당 컴포넌트는 Cilent Component로 간주된다.



어떤 컴포넌트가 Cilent Component가 되어야 하는가?

상호작용이 필요하다 -> Cilent Component

상호작용이 필요하지 않다 -> Server Component

  • Link 태그 같은 것은 HTML 고유의 기능이므로 상호작용이 아니다.
    -> JavaScript의 기능을 사용하는 것이 상호작용.



Layout에서 Cilent Component 설정이 가능하다.

  • Next.js의 동작 원리는, Layout 컴포넌트가 먼저 실행되고 페이지 컴포넌트가 Props로 받아와서 그 다음 순서로 진행되는 것이기 때문.

  • 다만, 하위 페이지 전체를 총괄하는 Layout 컴포넌트 특성상 여기에 직접 Cilent Component 설정을 걸어버리면 불필요한 컴포넌트들이 Cilent Component로 간주될 수 있다는 점은 주의.
    -> 따라서 되도록이면 Layout은 Server Component를 유지하고, 클라이언트에서 필요한 상호작용이 있는 특정 컴포넌트에만 use client 지시어를 사용하는 것이 좋다.



Co-Location

  • 페이지 폴더 내부에는 page 혹은 layout 컴포넌트 이외의 파일도 들어올 수 있다.

  • 개인 취향에 따른 문제이긴 하지만, 해당 페이지 컴포넌트에서 필요하지만 경로상으로 구분되는 것이 아닌 하위 컴포넌트는 그냥 같은 폴더에 넣어두어도 된다.



3. Server Component 사용시 주의사항.



Server Component에는 브라우저에서 실행되는 코드가 포함되면 안된다.

  • React Hook나 이벤트 핸들러, 브라우저쪽 라이브러리 등 브라우저에서만 실행할 수 있는 코드들은 당연히 Server Component에서 실행할 수 없다.



Cilent Component는 클라이언트에서만 실행되지 않는다.

  • Cilent Component는 2번 실행된다. 사전 렌더링에서 1번, JS Bundle 과정에서 1번으로 총 2번.
    -> 이름이 서버랑 클라이언트로 나뉘기 때문에 각각 자기 영역에서만 동작하는 것으로 오인하기 쉽다.
    -> 그런데 사실 Cilent Component라는 개념은 Server Component가 아닌 것들을 모두 총괄하는 뜻이지 클라이언트에서만 동작하는 것이 아니다.



Cilent Component에서 Server Component를 import할 수 없다.

  • Cilent Component는 서버와 브라우저에서 1번씩 실행된다.

  • 반면 Server Component는 서버에서만 1번 실행된다. 브라우저 단으로 넘어가지도 않는다.
    -> Server Component의 개념 자체가 JS Bundle에서 제외하기 위해 컴포넌트를 구분하는 것이기 때문.

  • 따라서 Cilent Component에서는 애초에 받아오지 않은 Server Component의 코드를 식별할 수가 없다.

  • 다만 Next.js에서는 위와 같은 문제가 발생하게 되면, 문제가 되는 Server Component 파트를 Cilent Component로 자동 변환해서 에러를 방지해주긴 한다.



Server Component에서 Cilent Component에게 직렬화할 수 없는 Props는 전달할 수 없다.

  • 데이터를 주고받거나 저장하기 위해서는 되도록 용량을 최소화하는 것이 좋다. 이 과정을 직렬화라고 칭한다.

  • 자바스크립트에서 함수는 직렬화가 불가능하다.
    -> 애초에 값들의 총합도 아니고, 기능 코드에 클로저 / 스코프 등의 정보들을 포함하고 있어서 이들을 단순화하는것이 어렵기 때문.

  • 즉, 함수는 Server Component에서 Cilent Component으로 Props로 전달할 수가 없다.
    -> React.js 시절과 다르게 함수를 Props로 넘기는 것이 자유롭지 않다는 것.

  • 사전 렌더링 과정을 조금 더 세부적으로 살펴보자. 서버 컴포넌트들이 실행된 뒤 React Server Component Payload (RSC Payload)라는 데이터 형태로 변환된다.

  • React Server Component를 직렬화하여 순수한 데이터 결과물로 전환하는 것. 여기에는 Server Component의 렌더링 결과 / 연결된 Cilent Component의 위치 / Cilent Component로 전달하는 Props 등이 포함된다.

  • 그런데 함수는 직렬화 하기에는 너무 복잡한 구성이기 때문에, 전달이 불가능한 것.









00. 강의 소개.

profile
프론트엔드 개발자를 준비하고 있습니다.

0개의 댓글