Jin's Study

[Next.js] Hydration과 use client 본문

Front-end/Next.js

[Next.js] Hydration과 use client

PolarJin 2025. 5. 7. 20:33

1. Hydration이란?

📌 정의

Hydration은 서버에서 전달된 정적인 HTML에
클라이언트에서 JavaScript를 연결하여
인터랙션이 가능한 웹 페이지로 만드는 과정(이벤트 처리나 상태 변경이 가능하게 만드는)

 

과정 요약

  1. 서버가 HTML을 브라우저에 전달
  2. 브라우저는 정적인 HTML을 먼저 표시
  3. React의 JS가 실행되어 이벤트 핸들러, useState 등이 작동함 → 이게 hydration

 

 2. use client란?

📌 정의

use client는 해당 컴포넌트를 클라이언트 컴포넌트로 지정한다는 선언
기본적으로 Next.js는 모든 컴포넌트를 서버 컴포넌트로 취급
-> Next.js에서 해당 컴포넌트를 클라이언트에서 실행해야 함을 명시하는 선언문

 

항목 설명
기본값 모든 컴포넌트는 서버 컴포넌트(Server Component)
use client 선언 해당 컴포넌트를 브라우저에서 실행할 수 있게 함
필요한 이유 useState, useEffect, 이벤트 핸들러, window, localStorage 등은 브라우저에서만 작동하기 때문

왜 필요해?

Next.js는 기본적으로 **서버 컴포넌트(Server Component)**로 작동
하지만 다음 기능들은 클라이언트에서만 동작하므로 use client가 필요

 

상황 use client 필요 여부
useState, useEffect, useRef 사용 ✅ 필요
이벤트 핸들러(onClick 등) 사용 ✅ 필요
window, localStorage 접근 ✅ 필요
정적인 데이터만 렌더링 ❌ 불필요

 

예시

// app/components/Counter.tsx
'use client'
import { useState } from 'react'

export default function Counter() {
  const [count, setCount] = useState(0)
  return <button onClick={() => setCount(count + 1)}>{count}</button>
}

🔄 use client와 Hydration의 관계

  • use client를 선언한 컴포넌트는 브라우저에서 실행되고, hydration 대상이 됨
  • 즉, Next.js는 해당 컴포넌트가 클라이언트에서 동작하도록 JS를 로딩하고,
    그 컴포넌트를 동적으로 연결하여 인터랙션이 가능한 상태로 만듦

3. Server Component vs Client Component vs Hydration

항목 Server Component Client Component(use client)
기본 렌더링 위치 서버에서 렌더링 서버에서 먼저 렌더링 후 클라이언트에서 hydrate
JavaScript 필요 여부 ❌ 필요 없음 (hydration 없음) ✅ 브라우저에서 JS로 hydrate 필요
useState, useEffect ❌ 사용 불가 ✅ 사용 가능
상호작용 (버튼 클릭 등) ❌ 불가 ✅ 가능
장점 성능 최적화, JS 용량 줄이기 사용자 인터랙션 구현 가능
예시 용도 정적 콘텐츠, 서버 데이터 표시 폼, 모달, 카운터 등 인터랙티브 UI

 

🧩 Server Component

  • 서버에서 HTML로 렌더링됨
  • 브라우저는 해당 HTML을 보여주기만 함
  • Hydration 없음JS 다운로드 없음
    → 사용자가 JavaScript를 더 적게 받아도 됨
    성능, 로딩 속도 모두 향상

🧩 Client Component (use client)

  • 서버에서 HTML로 먼저 렌더링됨
  • 브라우저가 해당 컴포넌트를 Hydration하여
    JavaScript를 주입하고 이벤트/상태 동작을 활성화함

💡 둘 다 서버에서 렌더링은 하지만:

  • Server Component는 HTML만,
  • Client Component는 HTML + Hydration까지 진행

✨ 예시

// Server Component (기본)
export default async function PostList() {
  const res = await fetch('https://api/posts')
  const posts = await res.json()
  return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>
}
// Client Component (상호작용 필요 시)
'use client'
import { useState } from 'react'

export default function Counter() {
  const [count, setCount] = useState(0)
  return <button onClick={() => setCount(count + 1)}>{count}</button>
}

 

 

마무리 요약

개념 설명
Hydration 서버에서 받은 HTML을 브라우저에서 JS로 연결하는 과정
use client 해당 컴포넌트를 클라이언트에서 실행되도록 지정
Server Component hydration이 없어 빠르고 가벼움
Client Component JS를 사용해 동적 UI를 구현할 수 있음
최적화 전략 가급적 Server Component를 활용하고, 꼭 필요한 부분만 Client로 분리