"use client"와 Hydration

Odyssey·2025년 1월 7일
0

Next.js_study

목록 보기
6/58
post-thumbnail

2025.1.7 수요일의 공부기록

Next.js에서는 서버 컴포넌트(Server Components)클라이언트 컴포넌트(Client Components)를 구분해서 사용할 수 있다.
이 중 "use client"는 특정 컴포넌트를 클라이언트 컴포넌트로 지정할 때 사용하는 지시문이다. 하지만 "use client"를 추가한다고 해서 SSR(Server-Side Rendering)이 자동으로 비활성화되는 것은 아니다.


"use client"란 무엇인가?

Next.js 13부터 React의 서버 컴포넌트와 클라이언트 컴포넌트를 구분해서 사용하는 방식이 도입됐다.
기본적으로 Next.js는 모든 컴포넌트를 서버 컴포넌트로 처리하지만, 클라이언트 컴포넌트로 지정하려면 코드 상단에 "use client"를 선언해야 한다.

클라이언트 컴포넌트의 특징

  1. 브라우저에서 실행된다.
  2. React Hook(useState, useEffect 등)을 사용할 수 있다.
  3. DOM 조작과 브라우저 전용 API를 사용할 수 있다.

"use client"와 SSR

"use client"를 추가한다고 해서 SSR이 완전히 비활성화되는 것은 아니다.
Next.js는 클라이언트 컴포넌트도 기본적으로 서버에서 초기 HTML을 렌더링한 후 브라우저에서 하이드레이션 과정을 거친다.

클라이언트 컴포넌트 예시

"use client";

import { useState } from "react";

export default function ClientComponent() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

동작 방식

  1. 서버에서 초기 HTML이 생성된다(SSR).
  2. 브라우저가 HTML을 받아 React 상태와 연결(하이드레이션)한다.
  3. 상태 관리와 이벤트 처리 등은 브라우저에서만 동작한다.

SSR을 비활성화하려면?

"use client"만으로는 SSR이 비활성화되지 않는다.
완전히 클라이언트에서만 렌더링하려면 아래 방법을 사용해야 한다.

방법 1: dynamic Import와 ssr: false

Next.js의 dynamic을 사용해 컴포넌트를 동적으로 로드하면서, ssr: false 옵션을 설정하면 해당 컴포넌트는 클라이언트에서만 렌더링된다.

import dynamic from "next/dynamic";

const ClientOnlyComponent = dynamic(() => import("../components/ClientComponent"), {
  ssr: false,
});

export default function Page() {
  return (
    <div>
      <h1>Client Only</h1>
      <ClientOnlyComponent />
    </div>
  );
}

동작

  • ClientOnlyComponent는 서버에서 렌더링되지 않는다.
  • 브라우저에서만 렌더링이 이루어진다.

방법 2: 클라이언트 데이터 Fetching

데이터 Fetching을 클라이언트 측에서 처리하도록 설정하면 해당 컴포넌트는 클라이언트 전용으로 동작한다.

"use client";

import { useState, useEffect } from "react";

export default function ClientOnly() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch("/api/data")
      .then((res) => res.json())
      .then((data) => setData(data));
  }, []);

  if (!data) return <p>Loading...</p>;

  return <div>{JSON.stringify(data)}</div>;
}

동작

  1. 데이터 Fetching은 브라우저에서만 이루어진다.
  2. 서버는 초기 렌더링을 처리하지 않는다.

"use client"와 기본 렌더링 동작 비교

항목서버 컴포넌트(Server Component)클라이언트 컴포넌트(Client Component)
기본 렌더링 방식서버에서 HTML 생성 (SSR)초기 렌더링은 서버에서 수행, 이후 브라우저에서 하이드레이션
React Hook 사용 여부불가능가능
브라우저 전용 API 사용 여부불가능가능
SSR 비활성화 방법불가능dynamicssr: false 필요

하이드레이션(Hydration)이란?

하이드레이션(Hydration)은 서버사이드 렌더링(SSR)을 통해 생성된 정적인 HTML에 클라이언트 측의 React를 연결하여 인터랙티브한 React 컴포넌트로 변환하는 과정을 말한다.


하이드레이션의 작동 방식

  1. 서버에서 HTML 생성
    Next.js와 같은 SSR 환경에서는 서버에서 초기 HTML을 생성하여 브라우저에 전달한다.
    이 HTML은 정적이며, 아직 React의 상태 관리나 이벤트 핸들링 기능이 없다.

  2. 클라이언트에서 자바스크립트 로드
    클라이언트는 자바스크립트를 로드하여 서버에서 생성된 HTML과 React의 상태 및 기능을 연결한다.

  3. React의 상태 및 이벤트 연결
    React는 하이드레이션 과정을 통해 HTML 구조에 상태 관리와 이벤트 처리를 추가하여 동작 가능한 인터랙티브 컴포넌트로 변환한다.


하이드레이션의 정의

"서버 환경에서 이미 렌더링된 HTML에 React를 붙이는 과정"
즉, 정적 HTML을 클라이언트 측 자바스크립트를 통해 동적으로 만드는 것이다.


하이드레이션의 장점과 단점

장점

  1. 빠른 초기 로딩
    SSR을 통해 생성된 HTML은 정적이기 때문에 브라우저가 빠르게 렌더링할 수 있다.

  2. SEO 친화적
    초기 HTML이 서버에서 생성되므로 검색 엔진 크롤러가 쉽게 접근할 수 있다.

  3. React의 동적 기능 추가
    클라이언트 측에서 React의 상태 관리와 이벤트 핸들링을 활성화하여 동적인 웹 페이지를 제공할 수 있다.

단점

  1. 추가적인 자바스크립트 로드 필요
    하이드레이션 과정에서는 클라이언트 측에서 추가적으로 자바스크립트를 로드해야 하므로 성능에 영향을 줄 수 있다.

  2. 복잡성 증가
    서버에서 HTML을 생성하고, 클라이언트에서 이를 React로 연결하는 과정은 구현과 디버깅이 다소 복잡할 수 있다.


하이드레이션 과정 예시

1. 서버에서 HTML 생성 (SSR)

서버는 다음과 같은 정적 HTML을 생성하여 브라우저에 전달한다:

<div id="root">
  <p>Count: 0</p>
  <button>Increase</button>
</div>

2. 클라이언트에서 React 연결 (하이드레이션)

React는 위 HTML을 기반으로 클라이언트 측에서 상태와 이벤트를 추가한다:

import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increase</button>
    </div>
  );
}

동작 결과

  • 브라우저는 정적 HTML을 먼저 렌더링한다.
  • 클라이언트 측에서 React가 연결되면서 버튼 클릭 등의 이벤트가 활성화된다.

하이드레이션과 CSR, SSR 비교

특징SSR + 하이드레이션CSR
초기 로딩 속도빠름 (HTML 미리 생성됨)느림 (자바스크립트 로드 후 렌더링 시작)
SEO 지원우수제한적
동적 기능 활성화하이드레이션 과정에서 동작 시작클라이언트 렌더링 완료 후 동작
복잡성서버와 클라이언트의 협력 필요클라이언트에서만 처리 (단순)

하이드레이션을 최적화하는 방법

  1. 필요한 부분만 하이드레이션
    React의 클라이언트 컴포넌트서버 컴포넌트를 분리하여 필요한 컴포넌트만 클라이언트에서 하이드레이션하도록 설계한다.

  2. 지연 로드(Lazy Loading)
    dynamic import를 사용해 특정 컴포넌트를 동적으로 로드하여 초기 하이드레이션 부담을 줄인다.

  3. 경량 데이터 사용
    서버에서 전달되는 HTML과 데이터를 최소화하여 하이드레이션 속도를 높인다.

0개의 댓글