누구나 로고
Online CoursesFor BusinessLibraryTrend InsightsFree coursesNoticesContactCareers
모든 강의를 무료로 볼 수 있어요. 회원가입 없이도 학습 가능합니다.
로그인무료 회원가입
강좌리액트 입문 — 컴포넌트로 만드는 웹27강

27강 / 전체 28강

환경변수와 빌드

4분 읽기 조회 0

Next.js 15 App Router를 활용해 SSR, SSG, Server Components의 개념과 리액트 SPA와의 차이, 실무에서의 선택 기준을 배웁니다.

🤔 Vite 리액트의 한계

지금까지 배운 Vite + React는 완전한 클라이언트 사이드 렌더링(CSR)입니다. 브라우저에서 JS를 다운받아 실행해야 화면이 보입니다. 이 방식의 한계:

  • SEO 불리: 검색 엔진 봇이 빈 HTML만 보게 됩니다.
  • 느린 초기 로딩: JS 다운로드 → 파싱 → 실행 → 렌더링 순서.
  • 소셜 공유 미리보기 없음: Open Graph 태그가 JS 실행 후 동적으로 추가되면 Twitter/KakaoTalk 미리보기가 안 됩니다.

이 문제를 해결하는 것이 Next.js입니다. 현재 버전 15에서는 App Router를 기본으로 사용합니다.

🏗️ 렌더링 전략 3가지

전략약자언제 HTML 생성적합한 페이지
정적 사이트 생성SSG빌드 타임마케팅, 블로그, 문서
서버 사이드 렌더링SSR요청 시마다개인화, 실시간 데이터
클라이언트 렌더링CSR브라우저에서대시보드, 인증 후 화면

Next.js App Router는 컴포넌트 단위로 이 전략을 섞어 사용할 수 있습니다. 기본적으로 모든 컴포넌트는 서버 컴포넌트입니다.

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

// app/posts/page.tsx — 서버 컴포넌트 (기본)
// 서버에서 실행 → HTML을 클라이언트로 전달
// useState, useEffect, onClick 사용 불가
// 데이터베이스 직접 접근, 환경변수 서버 전용 값 사용 가능

async function PostsPage() {
  // 서버에서 직접 DB 조회 또는 API 호출
  const posts = await fetch('https://api.example.com/posts').then((r) => r.json())

  return (
    <main>
      <h1>게시글 목록</h1>
      {posts.map((post: { id: number; title: string }) => (
        <div key={post.id}>{post.title}</div>
      ))}
    </main>
  )
}
// app/components/LikeButton.tsx — 클라이언트 컴포넌트
// 'use client' 선언 필수!
// useState, useEffect, 이벤트 핸들러 사용 가능

'use client'

import { useState } from 'react'

export function LikeButton({ postId, initialCount }: { postId: number; initialCount: number }) {
  const [count, setCount] = useState(initialCount)
  const [liked, setLiked] = useState(false)

  async function handleLike() {
    if (liked) return
    setLiked(true)
    setCount((c) => c + 1)
    await fetch(`/api/posts/${postId}/like`, { method: 'POST' })
  }

  return (
    <button onClick={handleLike} className={liked ? 'text-red-500' : 'text-gray-400'}>
      ❤️ {count}
    </button>
  )
}

핵심 패턴: 서버 컴포넌트로 데이터를 가져오고, 클라이언트 컴포넌트를 인터랙션 필요한 곳에만 배치합니다. 이렇게 하면 JS 번들 크기가 최소화되고 초기 로딩이 빨라집니다.

📁 App Router 파일 구조

app/
├── layout.tsx        # 전체 레이아웃 (HTML, body 포함)
├── page.tsx          # / 경로
├── loading.tsx       # 로딩 중 표시 (자동 Suspense)
├── error.tsx         # 에러 표시 (자동 Error Boundary)
├── not-found.tsx     # 404 페이지
├── posts/
│   ├── page.tsx      # /posts 경로
│   └── [id]/
│       └── page.tsx  # /posts/:id 경로

파일 이름 규칙만으로 라우팅, 로딩 상태, 에러 처리가 자동으로 설정됩니다.

⚡ Next.js vs Vite + React — 언제 무엇을 선택할까

상황선택
SEO가 중요한 공개 사이트Next.js
초기 로딩 속도 중요Next.js
대시보드, 인증 후 화면만Vite + React (SPA)
빠른 프로토타입Vite + React
풀스택 (API + 프론트 함께)Next.js

✅ 정리

  • Next.js App Router: 서버에서 HTML을 생성해 SEO와 초기 로딩 속도 개선.
  • 서버 컴포넌트(기본): 데이터 패칭, DB 접근 / 클라이언트 컴포넌트('use client'): useState, 이벤트.
  • SEO 필요, 실시간 데이터, 풀스택이면 Next.js. 단순 SPA 대시보드면 Vite + React.

관련 주제

  • SSR
  • SSG
  • CSR
  • 서버 컴포넌트
  • 클라이언트 컴포넌트
  • App Router
  • 렌더링 전략
  • Open Graph
  • 빌드 타임
  • 개발·프로그래밍
  • 개발·프로그래밍 강의
  • 리액트 입문 — 컴포넌트로 만드는 웹
  • 무료강의
  • 무료 온라인 강의
  • NUGUNA
  • 누구나
이전 26강에러 처리와 경계다음 28강 배포하기

댓글

0/1000

불러오는 중...

목차

  1. 1.리액트란 무엇인가
  2. 2.개발 환경 만들기 — Vite
  3. 3.JSX 기초
  4. 4.컴포넌트 만들기
  5. 5.Props로 데이터 전달
  6. 6.State와 useState
  7. 7.이벤트 처리
  8. 8.조건부 렌더링
  9. 9.리스트 렌더링과 key
  10. 10.폼 다루기
  11. 11.useEffect 기초
  12. 12.데이터 가져오기(fetch)
  13. 13.상태 끌어올리기
  14. 14.컴포넌트 합성과 재사용
  15. 15.useRef와 DOM 접근
  16. 16.커스텀 훅 만들기
  17. 17.Context API
  18. 18.useReducer
  19. 19.리스트 앱 실전 ①
  20. 20.리스트 앱 실전 ②
  21. 21.라우팅 — React Router
  22. 22.스타일링 방법들
  23. 23.리스트·상세 페이지 연결
  24. 24.비동기 상태 관리 패턴
  25. 25.성능 기초 — memo
  26. 26.에러 처리와 경계
  27. 27.환경변수와 빌드
  28. 28.배포하기

Support

  • Notices
  • FAQ
  • Contact Us
  • Community

Help & Info

  • Terms of Service
  • Privacy Policy
  • Refund Policy

Services

  • About Us
  • Sign up
  • New courses
  • Free courses
누구나 로고
Terms of ServicePrivacy PolicyRefund Policy

상호명: NUGUNA  |  대표자: 정우진  |  사업자등록번호: 392-32-01817  |  통신판매업신고: 제 2026-서울양천-0564 호

주소: 서울특별시 양천구 목동서로 100  |  이메일: nugunapass@gmail.com  |  전화: 010-6395-3043

© 2026 NUGUNA. All rights reserved.

KB예금주인증관리자
HomeCoursesLibraryContactMY