ReactReact 기초강의 10개 중 9번째난이도 기초

React Router — SPA 라우팅 구현

발행 읽는 시간 약 1 분

  • React
  • ReactRouter
  • 라우팅
  • SPA
  • navigate

강의 소개

React Router v6로 싱글페이지 앱에서 페이지 라우팅을 구현합니다. 동적 라우트, 중첩 라우트, 라우트 보호, 프로그래밍 방식 이동을 배웁니다.

React Router 설치#

Bash
npm install react-router-dom

기본 라우팅 설정#

TSX
// src/App.tsx
import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom";
import HomePage from "./pages/HomePage";
import UserListPage from "./pages/UserListPage";
import UserDetailPage from "./pages/UserDetailPage";
import NotFoundPage from "./pages/NotFoundPage";
import Layout from "./components/Layout";

function App() {
    return (
        <BrowserRouter>
            <Routes>
                <Route path="/" element={<Layout />}>
                    <Route index element={<HomePage />} />
                    <Route path="users" element={<UserListPage />} />
                    <Route path="users/:id" element={<UserDetailPage />} />
                    <Route path="*" element={<NotFoundPage />} />
                </Route>
            </Routes>
        </BrowserRouter>
    );
}

Layout과 Outlet#

TSX
// src/components/Layout.tsx
import { Outlet, NavLink } from "react-router-dom";

function Layout() {
    return (
        <div>
            <nav>
                {/* NavLink: 활성 경로에 active 클래스 자동 추가 */}
                <NavLink to="/" end>홈</NavLink>
                <NavLink to="/users">사용자</NavLink>
            </nav>

            <main>
                {/* 자식 라우트가 여기에 렌더링 */}
                <Outlet />
            </main>
        </div>
    );
}

동적 라우트#

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

function UserDetailPage() {
    const { id } = useParams<{ id: string }>();
    const { data: user, loading } = useFetch<User>(`/api/users/${id}`);

    if (loading) return <Spinner />;
    return <div>{user?.name}</div>;
}

쿼리 파라미터#

TSX
import { useSearchParams } from "react-router-dom";

function UserListPage() {
    const [searchParams, setSearchParams] = useSearchParams();

    const page = Number(searchParams.get("page") ?? "1");
    const query = searchParams.get("q") ?? "";

    function handleSearch(newQuery: string) {
        setSearchParams({ q: newQuery, page: "1" });
    }

    function goToPage(newPage: number) {
        setSearchParams({ q: query, page: String(newPage) });
    }

    return (
        <div>
            <input value={query} onChange={e => handleSearch(e.target.value)} />
            {/* URL: /users?q=철수&page=2 */}
        </div>
    );
}

프로그래밍 방식 이동#

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

function LoginForm() {
    const navigate = useNavigate();
    const { login } = useAuth();

    async function handleSubmit(e: FormEvent) {
        e.preventDefault();
        await login(email, password);
        navigate("/dashboard");           // 이동
        // navigate(-1);                  // 뒤로 가기
        // navigate("/login", { replace: true });  // 히스토리 교체
    }
}

라우트 보호 (Protected Routes)#

TSX
function ProtectedRoute({ children }: { children: ReactNode }) {
    const { user } = useAuth();
    const location = useLocation();

    if (!user) {
        // 로그인 후 원래 가려던 곳으로 돌아오게 state 전달
        return <Navigate to="/login" state={{ from: location }} replace />;
    }

    return <>{children}</>;
}

// App.tsx에서
<Route path="dashboard" element={
    <ProtectedRoute>
        <DashboardPage />
    </ProtectedRoute>
} />

TSX
import { Link, NavLink } from "react-router-dom";

// Link: 단순 이동
<Link to="/about">소개</Link>

// NavLink: 현재 경로와 일치 여부 스타일 적용
<NavLink
    to="/users"
    className={({ isActive }) => isActive ? "active" : ""}
>
    사용자
</NavLink>

정리#

Hook/컴포넌트역할
BrowserRouter라우터 제공자
Routes, Route라우트 정의
Outlet자식 라우트 렌더링 위치
Link, NavLink페이지 이동 링크
useParamsURL 동적 파라미터
useSearchParams쿼리 파라미터
useNavigate프로그래밍 이동
Navigate리다이렉트

다음 편에서는 React 실전 프로젝트 — 지금까지 배운 모든 내용을 활용한 투두 앱을 만듭니다.

Follow · Ask · Work

이 글이 도움이 됐다면

짧은 작업 기록과 데모는 인스타그램에 올립니다. 만들고 싶은 것이 있다면 프로젝트 의뢰나 협업 제안도 편하게 보내 주세요.

글쓴이

파란여우

직접 만든 AI 앱·제품의 개발·배포를 공개하는 실전형 테크 크리에이터

파란여우 소개 Instagram @bluefox._.hi

이어서 보기

만들고 싶은 것이 있다면 프로젝트 의뢰로 알려 주세요.