챗봇 공부 노트

[3편] App Router 구조, SPA개념

frontend-diary-log 2026. 1. 15. 19:12

📘 Aura_AI Day 3 — App Router 구조 이해 & SPA·Server/Client 개념 정리 (Next.js 핵심)

안녕하세요.
이번 글에서는 Aura_AI 프로젝트 Day 3에서 진행한 개념 정리 내용을 바탕으로,
React와 Next.js의 핵심 구조와 SPA/Server-Client 구분까지 정리했습니다.

실제 코딩보다 구조와 기준 이해가 더 중요한 날이었고,
이 기준이 잡혀야 이후 기능 구현과 면접 설명이 훨씬 수월해집니다.


1️⃣ 지금 프로젝트는 SPA인가요?

❓ 결론부터 말씀드리면,
부분적으로 SPA처럼 동작하지만, 전통적인 SPA는 아닙니다.

🔹 전통적인 SPA (React CRA 기준)

  • 최초에 HTML을 한 번만 로드
  • 이후 페이지 이동은 JS로 처리
  • 서버는 거의 API만 담당
    👉 모든 렌더링이 클라이언트에서 발생

🔹 Next.js App Router 방식

  • 페이지 단위로 서버에서 렌더링 가능
  • 필요하면 클라이언트 컴포넌트도 섞어 사용 가능
  • 페이지 이동은 SPA처럼 부드럽게 처리
  • 서버에서 만든 HTML을 클라이언트에서 자바스크립트가 이어받는 과정(Hydration) 포함

📌 면접용 한 줄 정리

Next.js는 SPA처럼 부드럽게 동작하지만, 서버 렌더링을 기본으로 하는 하이브리드 구조입니다.


2️⃣ App Router에서 가장 중요한 개념: Server Component

기본 규칙

  • app/ 폴더 안의 모든 컴포넌트는 기본적으로 Server Component
  • useState, useEffect 같은 브라우저 API는 ❌
  • 서버에서 HTML을 만들어 내려줌
export default function Page() {
  return <div>Hello</div>;
}

장점

  • 초기 로딩 빠름
  • SEO 유리
  • 보안 강함
  • 번들 사이즈 감소

Next.js가 React 위에서 만들어진 이유가 여기에 있습니다.


3️⃣ use client는 무엇인가요?

🔹 정체

"이 파일은 브라우저에서 실행될 겁니다"라는 선언

"use client";

import { useState } from "react";

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

📌 언제 필요한가요?

상황사용 여부

클릭 이벤트
useState
useEffect
단순 UI 출력
layout

필요한 곳에만 최소한으로 사용해야 서버 컴포넌트 장점을 살릴 수 있습니다.


4️⃣ Sidebar에 Link 넣으면 서버 컴포넌트인데 괜찮나요?

✅ 전혀 문제 없습니다.

import Link from "next/link";
  • 서버 컴포넌트에서도 Link 사용 가능
  • Next.js가 내부적으로 처리 → Hydration 문제 없음

❌ 잘못된 오해

  • “Link 쓰면 use client 붙여야 한다” ❌
  • “네비게이션은 클라이언트 컴포넌트다” ❌

📌 기준 정리

컴포넌트Server / Client

Header Server
Footer Server
Sidebar Server
버튼 클릭 Client
모달 Client

5️⃣ 파일 구조 (실무 기준)

기본 원칙

  • 페이지는 조립만 담당
  • 로직과 UI는 컴포넌트로 분리
app/
├─ layout.tsx           ← RootLayout: html/body, 폰트
├─ globals.css          ← 공통 스타일

├─ (public)/            ← 로그인 전 영역
│  ├─ layout.tsx        ← Header + Footer
│  ├─ page.tsx          ← Home 최소 JSX
│  ├─ login/page.tsx
│  ├─ signup/page.tsx
│  ├─ terms/page.tsx
│  ├─ privacy/page.tsx
│  ├─ about/page.tsx
│  ├─ support/page.tsx
│  └─ notice/page.tsx

├─ (auth)/              ← 로그인 후 영역
│  ├─ layout.tsx        ← Header + Sidebar
│  ├─ chat/page.tsx     ← 최소 JSX
│  └─ mypage/page.tsx   ← 최소 JSX

components/
├─ layout/
│  ├─ Header.tsx
│  ├─ Footer.tsx
│  └─ Sidebar.tsx
├─ chat/
├─ auth/
└─ common/

최소 JSX 예시

export default function ChatPage() {
  return (
    <main>
      <h1>Chat Page</h1>
    </main>
  );
}

 

layout.tsx

export default function PublicLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return <>{children}</>;
}

app/(auth)/layout.tsx는 (auth) 경로 그룹 전체의 공통 래퍼입니다.

이 파일의 children은 그 레이아웃 안에서 실제로 렌더되는 하위 페이지들(예: chat/page.tsx, mypage/page.tsx)을 의미

  • layout.tsx 역할: 해당 폴더(및 하위 경로)에 공통 UI·스타일·로직(예: 사이드바, 인증 체크, 메타)을 제공하고, 내부 페이지가 반복해서 사용하는 ‘틀(frame)’을 만듭니다.
  • children 의미: 레이아웃 내부에 삽입되는 React 요소들 — Next.js가 자동으로 현재 라우트의 page 컴포넌트를 children으로 전달합니다.
  • 영향: 레이아웃은 같은 세그먼트 내에서 내비게이션할 때 유지(persistent) 되어 상태(사이드바 열림 여부 등)를 보존합니다.

6️⃣ SPA와 Server/Client 컴포넌트 핵심

  • SPA처럼 보이는 이유: 페이지 이동이 부드럽게 처리
  • Server Component 기본: 초기 HTML 렌더링 → 빠른 로딩
  • Client Component 최소화: 상태, 이벤트가 필요한 경우에만
  • Link 사용 가능: 서버 컴포넌트에서도 문제 없음

7️⃣ Day 3의 핵심 학습 포인트

  • SPA를 맹목적으로 쓰지 않는다
  • Server / Client 역할을 명확히 구분한다
  • Next.js를 Next.js답게 사용한다

이 기준을 이해하면, 이후 상태 관리, 인증, GPT 연동까지 모두 쉽게 진행할 수 있습니다.


8️⃣ 면접에서 이렇게 말하면 됩니다

Q. 이 프로젝트는 SPA인가요?

SPA처럼 동작하지만, 서버 렌더링을 기본으로 하는 하이브리드 구조입니다.

Q. use client는 언제 쓰나요?

상태나 이벤트처럼 브라우저에서만 필요한 경우에만 사용합니다.

Q. Sidebar는 서버 컴포넌트인데 Link를 써도 되나요?

next/link는 서버 컴포넌트에서도 사용 가능해서, 레이아웃은 서버 컴포넌트로 유지했습니다.

Q. 모든 파일에 use client를 붙이지 않은 이유는?

불필요하게 붙이면 서버 컴포넌트 장점을 포기하게 되므로, 꼭 필요한 곳에서만 최소화했습니다.


9️⃣ 마무리

Day 3의 핵심은 코딩이 아니라 구조와 기준 정립이었습니다.

  • SPA를 맹목적으로 쓰지 않고
  • Server / Client 역할을 구분하고
  • Next.js를 Next.js답게 사용하는 것

이 기준이 확실하면, 이후 기능 개발과 면접 대응이 모두 수월해집니다.