라우팅이란 기본 구성 페이지 이동 동적 라우팅 중첩·NotFound 📝 문제풀이
◀ 이전 📋 목차 CH 14 ▶
🧭 CHAPTER 13 · 고급

URL에 따라 화면을 바꾸기 — 라우팅

SPA는 페이지 하나로 도는데, 어떻게 /about, /user/3 같은 주소마다 다른 화면을 보여줄까요? 그 답이 라우팅(routing)이고, 리액트에서는 React Router라는 라이브러리로 해결합니다. 차근차근 따라가 볼게요.

🎯 이 장을 끝내면
🧭
라우팅이란
SPA에서 "라우팅"이 뭔가요?
주소에 따라 다른 화면을 보여주는 일이에요.

라우팅(routing)URL(주소)에 따라 서로 다른 컴포넌트(화면)를 보여주는 일이에요. 예를 들어 /에서는 홈 화면, /about에서는 소개 화면, /user/3에서는 3번 사용자 화면을 띄우는 식이죠.

전통적인 웹은 주소가 바뀌면 서버에서 새 HTML 페이지를 통째로 받아 화면을 갈아끼웠어요. 하지만 SPA(단일 페이지 앱)는 페이지를 새로 받지 않아요. 대신 주소만 바꾸고, 그 주소에 맞는 컴포넌트를 자바스크립트로 그려서 갈아끼웁니다.

📄
전통적인 웹
주소가 바뀌면 서버에서 새 HTML을 통째로 받아 화면을 갈아끼움. 매번 깜빡임.
vs
SPA
페이지는 그대로 두고 주소만 바꿔 컴포넌트만 갈아끼움. 새로고침 없이 매끄러움.
🔤
SPA(Single Page Application, 단일 페이지 앱) — 페이지를 딱 하나만 불러온 뒤, 이후에는 새 페이지를 받지 않고 자바스크립트로 화면 내용만 갈아끼우는 방식의 웹앱이에요. 그래서 화면 전환이 깜빡임 없이 빠르고 매끄러워요.
🧩 리액트 자체엔 라우팅 기능이 없어요🟪 리액트 리액트는 CH 01에서 배웠듯 화면(UI)을 그리는 일에만 집중하는 라이브러리예요. 그래서 라우팅은 리액트에 기본으로 들어있지 않고, 별도의 라이브러리를 붙여서 씁니다. 가장 널리 쓰이는 게 바로 React Router예요. 이번 장의 모든 예제는 React Router 기준이에요. npm install react-router-dom으로 설치해서 씁니다.
라우팅(Routing) React Router BrowserRouter Routes / Route Link useParams useNavigate path="*"
🧭
핵심 한 줄. "라우팅 = 주소마다 다른 컴포넌트를 보여주기." SPA에서는 페이지를 새로 안 받고, React Router가 URL을 보고 알맞은 컴포넌트로 갈아끼워요.
🧱
기본 구성
BrowserRouter · Routes · Route
이 세 가지로 "경로 → 컴포넌트" 지도를 그려요.

React Router의 뼈대는 세 가지예요. <BrowserRouter>앱 전체를 감싸고, 그 안에 <Routes>를 두고, <Routes> 안에 <Route>를 여러 개 나열해 경로와 컴포넌트를 짝지어요.

<BrowserRouter> · 라우팅 켜기 (앱을 감쌈)
<Routes> · URL에 맞는 하나만 골라 보여줌
<Route path="/">
→ Home
<Route path="/about">
→ About
구성 요소역할
<BrowserRouter>앱을 감싸 라우팅 기능을 켜는 최상위 껍데기. 브라우저의 주소(URL)를 관리해요. 보통 앱에 딱 한 번만 써요.
<Routes>여러 <Route>를 담는 상자. 현재 URL과 가장 잘 맞는 하나를 골라 보여줘요.
<Route>path(경로)와 element(보여줄 컴포넌트)를 짝지어요. 예: path="/about"<About />

코드로 보면 이렇게 생겼어요. path에는 주소 문자열을, element에는 보여줄 컴포넌트를 넣습니다.

import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./Home";
import About from "./About";

function App() {
  return (
    <BrowserRouter>
      <Routes>
        {/* path="/" 일 때 Home 컴포넌트를 보여줌 */}
        <Route path="/" element={<Home />} />
        {/* path="/about" 일 때 About 컴포넌트를 보여줌 */}
        <Route path="/about" element={<About />} />
      </Routes>
    </BrowserRouter>
  );
}
💡
읽는 법. <Route path="/about" element={<About />} />는 "주소가 /about이면 About 컴포넌트를 그려라"라는 뜻이에요. element에는 컴포넌트 태그(<About />)를 넣는다는 점을 기억하세요.
🔗
페이지 이동
Link로 이동하기 (a 태그 대신)
새로고침 없이 매끄럽게 화면을 바꿔요.

화면 사이를 오갈 때는 <a href>가 아니라 React Router가 주는 <Link>를 씁니다. 목적지는 to 속성에 적어요.

import { Link } from "react-router-dom";

function Nav() {
  return (
    <nav>
      {/* to 에 목적지 경로를 적어요 */}
      <Link to="/">홈</Link>
      <Link to="/about">소개</Link>
    </nav>
  );
}
🆚 왜 <a>가 아니라 <Link>일까?🟪 리액트 <a href="/about"> — 브라우저가 서버로 새 요청을 보내 페이지 전체를 새로 받아요. 화면이 깜빡이고, 리액트 앱이 처음부터 다시 로딩돼 state가 모두 초기화돼요. (SPA의 장점이 사라짐)
<Link to="/about">새로고침 없이 주소만 바꾸고 필요한 컴포넌트만 갈아끼워요. 앱은 계속 켜진 채, 화면만 매끄럽게 전환돼요. 한 줄 정리: SPA 안에서의 이동은 반드시 <Link>로. <a>를 쓰면 전체 새로고침이 일어나 SPA의 이점이 날아갑니다.
⚠️
겉모습만 보면 <Link>도 최종적으로는 <a> 태그로 그려져요. 하지만 클릭을 React Router가 가로채 새로고침을 막고 SPA 방식으로 이동시킨다는 점이 다릅니다.
🎯
동적 라우팅
URL 파라미터 · useParams · useNavigate
/user/3, /user/7 처럼 값이 바뀌는 경로를 다뤄요.

사용자마다 /user/1, /user/2 … 처럼 주소의 일부가 바뀌는 경우가 많죠. 이럴 때 path콜론(:)을 붙인 자리표시자를 씁니다. path="/user/:id"라고 하면 :id 부분이 어떤 값이든 매칭돼요.

🔤
동적 라우트 — /user/1, /user/2처럼 일부가 값에 따라 바뀌는 경로예요. 바뀌는 자리를 :id 같은 자리표시자(placeholder)로 표시하면, 그 자리에 어떤 값이 와도 같은 화면(컴포넌트)이 매칭돼요.
{/* :id 자리에 아무 값이나 들어올 수 있어요 */}
<Route path="/user/:id" element={<User />} />

그럼 컴포넌트 안에서는 그 :id 값을 어떻게 읽을까요? useParams() 훅을 씁니다. URL 파라미터들을 객체로 돌려줘요.

import { useParams } from "react-router-dom";

function User() {
  // /user/3 로 접속하면 id 는 "3"
  const { id } = useParams();
  return <h1>{id}번 사용자 페이지</h1>;
}

버튼 클릭 같은 코드 로직 안에서 이동시키고 싶을 때는 <Link>가 아니라 useNavigate() 훅을 씁니다. 이걸 프로그래밍적 이동이라고 해요.

import { useNavigate } from "react-router-dom";

function LoginButton() {
  const navigate = useNavigate();

  function handleLogin() {
    // ...로그인 처리 후...
    navigate("/dashboard");   // 코드로 페이지 이동!
  }

  return <button onClick={handleLogin}>로그인</button>;
}
🔗
<Link to>
사용자가 직접 클릭
vs
🤖
useNavigate()
코드에서 이동시킴
(로그인 후 등)
💡
정리. :id로 동적 경로를 만들고 → useParams()로 그 값을 읽고 → 코드에서 이동은 useNavigate(). 이 3종 세트가 동적 라우팅의 핵심이에요.
🪜
중첩·NotFound
중첩 라우트와 없는 경로 처리
레이아웃 공유와 404 화면을 간단히 짚어요.

중첩 라우트(Nested Routes)<Route> 안에 또 <Route>를 넣는 방식이에요. 공통 레이아웃(예: 사이드바)을 부모 라우트가 감싸고, 그 안쪽 화면만 자식 라우트로 바꿔 끼울 때 씁니다. 부모가 자식이 그려질 자리를 <Outlet />로 표시해요.

그리고 정의한 어떤 경로에도 맞지 않는 주소가 들어오면? path="*"를 쓰면 "위의 모든 경로에 안 맞는 나머지"를 잡아요. 여기에 보통 NotFound(404) 화면을 연결합니다.

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />} />
  <Route path="/user/:id" element={<User />} />

  {/* 위 어떤 것에도 안 맞으면 여기로 → 404 화면 */}
  <Route path="*" element={<NotFound />} />
</Routes>
🧭
path="*""못 찾은 경로 전부"를 의미하는 와일드카드예요. 사용자가 오타로 /abuot 같은 주소로 들어와도 앱이 깨지지 않고 친절한 404 화면을 보여줄 수 있어요.
🧠 이 장 핵심 요약
📝
문제풀이 · 점검
배운 걸 가볍게 점검해봐요
시험이 아니라 "내가 이해했나" 확인용이에요. 틀려도 바로 해설이 나와요.
🧪
문제를 풀면 즉시 정답과 해설이 나오고, 위쪽 바에 점수가 쌓여요. 네 가지 유형(객관식 · O/X · 빈칸 · 개념결과)을 섞어 두었어요.
CH 14 🌐 데이터 페칭 — 서버에서 데이터를 불러와 화면에 그리기