Vite와 React로 프로젝트를 구성할 때, 라우팅 구조를 어떻게 설계하느냐는 유지보수성과 가독성에 큰 영향을 미친다고 생각한다.
이 글에서는 React Router v6 기준으로, router.tsx 파일을 별도로 구성하여 라우팅 책임을 명확히 분리하는 구조를 소개한다.
기존 내가 했던 방식 (Vite)…
App.tsx에 라우팅 책임을 맡겼다.
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import NotFound from './pages/NotFound';
function App() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="*" element={<NotFound />} />
</Routes>
);
}
App.tsx의 SRP를 준수하지 못했다.
App.tsx는 사실 웹의 외피이다.
페이지도 아니고, 라우팅도 안하지만, 최상위 컴포넌트로서 지위는 있다.
뭐 아래와 같은걸 하겠다.
• 전역 스타일링 (styled-components, emotion, CSS reset 등)
• 상태 관리 Provider (Redux, Recoil, Zustand, Jotai, MobX 등)
• 쿼리 캐시 Provider (react-query, SWR 등)
• 테마 관리 (dark / light mode)
• 에러 바운더리 (ErrorBoundary)
• 언어 설정 (i18n)
• 토스트, 모달 등 앱 전역 공통 UI
발전된 버전 :기본 구조 설계
📦 src/
┣ 📄 main.tsx ← 앱 진입점, RouterProvider 실행
┣ 📄 App.tsx ← 전역 상태 및 Provider 관리
┣ 📂router/
┃ ┗ 📄 router.tsx ← 라우팅 정의 전용 파일
┣ 📂pages/ ← 개별 페이지 컴포넌트들
┣ 📂components/ ← 재사용 가능한 UI 컴포넌트들
🧩 main.tsx _ 진입점
- 앱을 브라우저에 마운트 하는 최상위 Entry Point
- RouterProvider에 내가 만든 router.tsx 라우팅 객체를 주입
비유적 표현으로 웹의 심장박동 시작버튼
import React from 'react';
import ReactDOM from 'react-dom/client';
import { RouterProvider } from 'react-router-dom';
import { router } from './router/router';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);
🧠 App.tsx - 전역 스탠드
앱의 컨트럴 타워로써
지금은 빈 껍데기지만 (Provider)이 없지만, 전역 상태나 테마 등을 추가하는 책임만을 부여한다.
function App({ children }: { children: React.ReactNode }) {
return <>{children}</>;
}
export default App;
🧭 router.tsx - 길잡이 역할
router.tsx는 사용자의 경로(Path)에 따라 어떤 페이지를 렌더링할지를 정의하는 중심 파일이다.
즉, 앱의 ‘길 안내 네비게이터’ 역할을 한다.”
import { createBrowserRouter } from 'react-router-dom';
import App from '../App';
import Layout from '../layouts/Layout';
import Home from '../pages/Home';
import NotFound from '../pages/NotFound';
export const router = createBrowserRouter([
{
path: '/',
element: (
<App>
<Layout />
</App>
),
children: [
{ path: '', element: <Home /> },
{ path: '*', element: <NotFound /> },
],
},
]);
💡 왜 이렇게 구성할까?
- Single Responsibility
- App.tsx는 앱 전체에 필요한 전역 Provider만 담당
- router.tsx는 페이지 이동과 관련된 라우팅 정의만 담당
- 테스트 및 유지보수 용이
- 각각의 책임이 분리되므로, 변경 시 영향을 최소화할 수 있음
- Next.js 스타일을 React에서도 구현 가능
- 구조적으로 레이아웃/라우팅/전역 상태 분리를 통해 Next.js의 장점을 일부 흡수할 수 있음
결론
Vite + React 환경에서는 코드 기반 라우팅을 어떻게 구조화하느냐에 따라 프로젝트의 품질이 결정된다.
router.tsx를 통해 명확하게 라우팅 책임을 분리하고,
App.tsx를 통해 전역 상태를 관리하는 구조는 확장성과 유지보수성을 크게 높여주는 효과를 기대 할 수 있다.
'FrontEnd Develop > Project : TODOMVC' 카테고리의 다른 글
Zustand X Generic 심층분석. (0) | 2025.04.09 |
---|