본문으로 건너뛰기
최서희Frontend Engineer
← 블로그

Frontend

[유데미 러닝크루] Next.js 스터디 2주차 – 리액트 서버 컴포넌트 vs 클라이언트 컴포넌트

· 4분 읽기

📑 목차

1. 2주차 진행 범위 & Udemy 강의 소개

📌 2주차 진행 범위

📝 세션 3 ~ 4 강의까지 진행

[Udemy 강의 소개]

이번 스터디에서 수강하는 강의는 【한글자막】 Next.js 15 & React - 완벽 가이드이다. 이 강의에서는 Next.js 15를 기초부터 학습하고, 앱 라우터 & 페이지 라우터를 활용하여 풀스택 앱을 구축하는 방법을 배울 수 있다.

💡 강의 정보

  • 강의명: 【한글자막】 Next.js 15 & React - 완벽 가이드
  • 강의 시간: 40시간
  • 수강생: 5,021명
  • 강의 평가: ⭐ 4.7/5 (585명 평가)
  • 언어: 한국어 자막 제공

📌 강의 주요 내용

✅ Next.js 15의 앱 라우터 & 페이지 라우터 학습 ✅ 서버/클라이언트 컴포넌트 이해 ✅ 서버 액션을 활용한 데이터 처리 ✅ SSR·파일 기반 라우팅·인증 기능 익히기

2. 2주차 학습 내용 정리 — Next.js 핵심

1️⃣ 서버 컴포넌트 vs 클라이언트 컴포넌트

  • Next.js의 모든 컴포넌트는 기본적으로 서버에서 실행됨.
  • 브라우저 전용 기능이 필요할 때 파일 최상단에 "use client"를 선언해 클라이언트 컴포넌트로 전환.

✅ 서버 컴포넌트 (기본)

  • 서버에서 HTML 생성 후 클라이언트로 전달 → SEO/초기속도 유리
  • console.log()는 서버 터미널에 출력
export default function ServerComponent() {
  console.log("서버에서 실행됨"); // 서버 터미널에서 확인 가능
  return <h1>서버 컴포넌트</h1>;
}

✅ 클라이언트 컴포넌트

  • 브라우저에서 동작. useState, useEffect, onClick 등 사용 시 필요
  • 파일 최상단에 "use client" 필수
"use client";
import { useState } from "react";

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

2️⃣ 서버 컴포넌트의 동작 방식

  • 기본적으로 서버에서 실행되어 HTML을 만들어 보냄.
  • console.log()는 브라우저 콘솔이 아닌 서버 터미널에서 확인.
  • 페이지 이동 시에도 서버에서 새 HTML을 렌더링해 전달.
export default function Example() {
  console.log("서버에서 실행됨"); // 서버 터미널에서 확인 가능
  return <h1>이 컴포넌트는 서버에서 렌더링됩니다.</h1>;
}

3️⃣ 클라이언트 컴포넌트가 필요한 경우

  • React 훅: useState, useEffect 등
  • 이벤트: onClick, onChange 등
  • 브라우저 API: localStorage, sessionStorage 등
"use client";
import { useState, useEffect } from "react";

export default function Timer() {
  const [time, setTime] = useState(0);

  useEffect(() => {
    const id = setInterval(() => setTime((t) => t + 1), 1000);
    return () => clearInterval(id);
  }, []);

  return <h1>타이머: {time}초</h1>;
}

4️⃣ 내비게이션 상태 관리 — usePathname()

현재 URL 경로를 읽어 활성 링크 강조 등 동적 내비게이션을 구현.

NavLink 컴포넌트 (CSS 모듈로 활성 클래스 지정)

"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import styles from "./nav-link.module.css";

export default function NavLink({ href, children }) {
  const pathname = usePathname();
  const isActive = pathname.startsWith(href);

  return (
    <Link href={href} className={isActive ? styles.active : ""}>
      {children}
    </Link>
  );
}

헤더(서버 컴포넌트)에서 사용 — 헤더는 서버로 유지하면서 링크만 클라이언트

import NavLink from "./NavLink";

export default function MainHeader() {
  return (
    <nav>
      <NavLink href="/meals">Browse Meals</NavLink>
      <NavLink href="/community">Foodies Community</NavLink>
    </nav>
  );
}

5️⃣ 클라이언트 컴포넌트 효율 사용 & 한계

  • 기본은 서버 컴포넌트. 꼭 필요한 부분만 "use client"로 분리.
  • 최소 영역에만 상태/이벤트/브라우저 API 적용.
  • usePathname()로 경로 기반 내비 최적화.

한계(과도 사용 시)

  • 성능 저하: 전송·실행할 JS 증가 → 초기 렌더 느려짐
  • 초기 로딩 지연: 서버 선렌더 이점 축소
  • SEO 불리: 콘텐츠가 클라이언트에서 늦게 그려질 수 있음

🔥 최종 정리

  • Next.js는 기본 서버 컴포넌트 — 성능·SEO에 유리.
  • 브라우저 기능이 필요한 최소 부분만 "use client"로 전환.
  • usePathname()으로 활성 경로를 감지, 내비게이션 상태 반영.
  • 과도한 클라이언트화는 JS 증가/초기속도/SEO에 악영향.

댓글

GitHub 계정으로 댓글을 남길 수 있어요.