frontend/react

[React] React.js 강좌 19. React Router로 대시보드 라우팅 구조 설계하기

mirabo01 2025. 11. 10. 08:54

1. SPA에서 라우팅이 필요한 이유

React는 기본적으로 단일 페이지 애플리케이션(SPA) 구조를 따릅니다.
즉, 화면 이동 시 실제로 페이지가 새로고침되지 않고
컴포넌트의 전환만 이루어집니다.

하지만 대시보드나 관리자 페이지처럼
여러 화면(예: 통계, 알림, 설정 등)을 구성할 때는
각 화면을 독립된 “페이지 단위”로 나누는 것이 훨씬 효율적입니다.

이를 가능하게 해주는 것이 바로 React Router입니다.


2. React Router 설치 및 기본 설정

먼저 패키지를 설치합니다.

npm install react-router-dom

그다음 프로젝트의 루트에서 BrowserRouter를 적용합니다.

// index.js
import { BrowserRouter } from 'react-router-dom';
import App from './App';

export default function Root() {
  return (
    <BrowserRouter>
      <App />
    </BrowserRouter>
  );
}

이제 App 내부에서 라우트를 정의할 수 있습니다.


3. 기본 라우트 구조

// App.js
import { Routes, Route } from 'react-router-dom';
import LoginForm from './LoginForm';
import Dashboard from './Dashboard';
import Settings from './Settings';
import NotFound from './NotFound';

export default function App() {
  return (
    <Routes>
      <Route path="/" element={<LoginForm />} />
      <Route path="/dashboard" element={<Dashboard />} />
      <Route path="/settings" element={<Settings />} />
      <Route path="*" element={<NotFound />} />
    </Routes>
  );
}

이렇게 하면

  • / → 로그인 페이지
  • /dashboard → 대시보드
  • /settings → 설정 페이지
    로 라우팅됩니다.

4. 내비게이션 바 추가

대시보드 내에서 페이지 간 전환을 위해 내비게이션 바를 만듭니다.

// Navbar.jsx
import { Link } from 'react-router-dom';

export default function Navbar() {
  const linkStyle = {
    marginRight: '15px',
    textDecoration: 'none',
    color: 'black',
    fontWeight: 500,
  };

  return (
    <nav style={{ borderBottom: '1px solid #ddd', padding: '10px' }}>
      <Link to="/dashboard" style={linkStyle}>홈</Link>
      <Link to="/dashboard/stats" style={linkStyle}>통계</Link>
      <Link to="/dashboard/notifications" style={linkStyle}>알림</Link>
      <Link to="/settings" style={linkStyle}>설정</Link>
    </nav>
  );
}

그다음, Dashboard에 포함시켜줍니다.

// Dashboard.jsx
import Navbar from './Navbar';

export default function Dashboard() {
  return (
    <div>
      <Navbar />
      <h2>대시보드 홈</h2>
      <p>사용자 정보를 불러오고 있습니다...</p>
    </div>
  );
}

5. 중첩 라우트 (Nested Routes)

대시보드 안에 여러 하위 페이지를 두려면 중첩 라우트를 사용해야 합니다.

// App.js
import DashboardLayout from './DashboardLayout';
import DashboardHome from './DashboardHome';
import DashboardStats from './DashboardStats';
import DashboardNotifications from './DashboardNotifications';

<Routes>
  <Route path="/" element={<LoginForm />} />
  <Route path="/dashboard" element={<DashboardLayout />}>
    <Route index element={<DashboardHome />} />
    <Route path="stats" element={<DashboardStats />} />
    <Route path="notifications" element={<DashboardNotifications />} />
  </Route>
</Routes>

DashboardLayout 안에서는 Outlet을 사용합니다.

// DashboardLayout.jsx
import { Outlet } from 'react-router-dom';
import Navbar from './Navbar';

export default function DashboardLayout() {
  return (
    <div>
      <Navbar />
      <div style={{ padding: '20px' }}>
        <Outlet /> {/* 하위 페이지가 이 자리에 렌더링됨 */}
      </div>
    </div>
  );
}

6. 하위 페이지 예시

// DashboardHome.jsx
export default function DashboardHome() {
  return <h3>📊 대시보드 요약 화면</h3>;
}

// DashboardStats.jsx
export default function DashboardStats() {
  return <h3>📈 사용자 통계 페이지</h3>;
}

// DashboardNotifications.jsx
export default function DashboardNotifications() {
  return <h3>🔔 최근 알림 페이지</h3>;
}

이제 /dashboard/stats로 이동하면 자동으로 해당 컴포넌트가 렌더링됩니다.


7. 로그인 상태 보호 (Private Route)

로그인하지 않은 사용자가 /dashboard에 직접 접근하는 것을 막으려면
PrivateRoute를 추가합니다.

// PrivateRoute.jsx
import { Navigate } from 'react-router-dom';
import { useAuthStore } from './authStore';

export default function PrivateRoute({ children }) {
  const { user } = useAuthStore();
  if (!user) return <Navigate to="/" replace />;
  return children;
}

이제 보호가 필요한 페이지를 이렇게 감쌉니다.

<Route
  path="/dashboard/*"
  element={
    <PrivateRoute>
      <DashboardLayout />
    </PrivateRoute>
  }
/>

8. 페이지 전환 애니메이션 (선택 사항)

라우트 전환 시 부드러운 UX를 원한다면
Framer Motion을 활용할 수 있습니다.

npm install framer-motion
import { motion } from 'framer-motion';

export default function DashboardHome() {
  return (
    <motion.div
      initial={{ opacity: 0, y: 10 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.3 }}
    >
      <h3>📊 대시보드 요약 화면</h3>
    </motion.div>
  );
}

간단히 적용할 수 있으며, 사용자 경험을 한층 향상시킵니다.


9. 라우트 코드 스플리팅

규모가 커질 경우 페이지별로 코드를 분리하여
초기 로딩 속도를 최적화할 수 있습니다.

import { lazy, Suspense } from 'react';
const DashboardStats = lazy(() => import('./DashboardStats'));

<Route
  path="stats"
  element={
    <Suspense fallback={<p>로딩 중...</p>}>
      <DashboardStats />
    </Suspense>
  }
/>

10. 마무리

이번 강의에서는 React Router를 이용해
대시보드 페이지 구조를 설계했습니다.

핵심 요약:

  • BrowserRouter, Routes, Route로 페이지 구성
  • Outlet을 이용한 중첩 라우트
  • PrivateRoute로 로그인 보호
  • Framer Motion으로 전환 애니메이션
  • 코드 스플리팅으로 성능 최적화

React Router는 SPA에서 화면을 논리적으로 분리해주기 때문에
대규모 프로젝트에서도 코드 유지보수가 쉬워집니다.

다음 강의에서는 이 구조에 React Query를 결합하여
페이지별 데이터 캐싱 및 전환 시 성능 최적화 방법을 다뤄보겠습니다.