Dynamic Route는 동적 라우팅이라고도 부르며
path에 유동적인 값을 포함해 특정 페이지로 이동하도록 구현하는 방식임.
// ❌️
<Route path="/works/1" element={<Works />} />
<Route path="/works/2" element={<Works />} />
<Route path="/works/3" element={<Works />} />
예를 들어 works 페이지에 여러 개의 work가 있고, 각 work마다 독립적인 상세 페이지가 필요하다고 가정함.
이 경우 works/1, works/2, works/3처럼 모든 경로를 하나씩 직접 작성하는게 아니라.
react-router-dom에서 제공하는 Dynamic Routes 기능을 사용해서 동적으로 변하는 경로를 간결하게 처리 가능함.
// src/shared/Router.js
import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Home from "../pages/Home";
import About from "../pages/About";
import Contact from "../pages/Contact";
import Works from "../pages/Works";
import Work from "../pages/Work";
const Router = () => {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
<Route path="works" element={<Works />} />
{/* path에 :id 사용 */}
<Route path="works/:id" element={<Work />} />
</Routes>
</BrowserRouter>
);
};
export default Router;
Works 페이지에 여러 개의 Work가 있고, 클릭 시 각각의 상세 페이지로 이동하도록 구현.
기존과 달리 path에 :id 사용함. :id는 동적인 값을 받겠다는 의미임.
따라서 works/1, works/2 … works/100 모두 같은 <Work /> 컴포넌트로 이동함.
이때 id 값은 useParams 훅을 통해 조회 가능.
Dynamic Routes를 사용하면
같은 페이지 컴포넌트(Work.js)를 모두 동일하게 렌더링하게 됨.
하지만 useParams를 사용하면
같은 컴포넌트를 렌더링 하더라도 각각 다른 id 값 조회 가능함.
useParams는 path의 있는 id 값을 조회할 수 있게 해주는 훅(path parameter 조회 목적).
예를 들어 works/100으로 이동하면 { id: "100" } 형태의 객체 반환함.
// src/pages/Works.js
import React from 'react';
import { Link } from 'react-router-dom';
const data = [
{ id: 1, todo: '리액트 배우기' },
{ id: 2, todo: '노드 배우기' },
{ id: 3, todo: '자바스크립트 배우기' },
{ id: 4, todo: '파이어 베이스 배우기' },
{ id: 5, todo: '넥스트 배우기' },
{ id: 6, todo: 'HTTP 프로토콜 배우기' },
];
function Works() {
return (
<div>
{data.map((work) => {
return (
<div key={work.id}>
<div>할일: {work.id}</div>
{/* 링크 목록추가 */}
<Link to={`/works/${work.id}`}>
<span style={{ cursor: 'pointer' }}>➡️ Go to: {work.todo}</span>
</Link>
</div>
);
})}
</div>
);
}
export default Works;
// src/pages/Work.js
import React from 'react';
import { useParams } from 'react-router-dom';
const data = [
{ id: 1, todo: '리액트 배우기' },
{ id: 2, todo: '노드 배우기' },
{ id: 3, todo: '자바스크립트 배우기' },
{ id: 4, todo: '파이어 베이스 배우기' },
{ id: 5, todo: '넥스트 배우기' },
{ id: 6, todo: 'HTTP 프로토콜 배우기' },
];
function Work() {
// useParams 사용
const param = useParams();
// param 객체에서 id 값 추출 가능.
// 해당 id를 기준으로 데이터 필터링 가능.
const work = data.find(
(work) => work.id === parseInt(param.id)
);
return <div>{work.todo}</div>;
}
export default Work;
중첩 라우팅은 특정 라우트 내부에 추가로 라우트를 정의하는 방식.
여러 계층의 UI 구성 시 유용함.
예시로 대시보드 구조가 있음.
/dashboard 하위에 여러 섹션 존재하는 구조임.
// src/shared/Router.js
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import DashboardLayout from './DashboardLayout';
import Profile from './Profile';
import Settings from './Settings';
import Reports from './Reports';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/dashboard" element={<DashboardLayout />}>
<Route index element={<Profile />} />
<Route path="settings" element={<Settings />} />
<Route path="reports" element={<Reports />} />
</Route>
</Routes>
</BrowserRouter>
);
}
/dashboard는 공통 레이아웃(DashboardLayout)을 사용함.
하위 경로마다 서로 다른 페이지 렌더링함.
라우트 구조가 명확해지고 UX 개선에 도움 됨.
자식 라우트가 렌더링될 위치를 지정하는 컴포넌트.
복잡한 라우트 구조를 명확하게 관리 가능함.
// src/shared/Router.js
import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Layout from './Layout';
import Home from "../pages/Home";
import About from "../pages/About";
const Router = () => {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="about" element={<About />} />
</Route>
</Routes>
</BrowserRouter>
);
};
export default Router;
// src/shared/Layout.js
import { Outlet } from 'react-router-dom';
function Layout() {
return (
<div>
<header>Header Section</header>
<main>
<Outlet /> {/* 이 위치에 자식 라우트의 컴포넌트 렌더링. */}
</main>
<footer>Footer Section</footer>
</div>
);
}
props와 chilren을 활용한 공통 Layout.
children은 어떤 자식 엘리먼트가 들어올지 모를 때 사용.
Sidebar, Dialog 같은 범용 컴포넌트에서 자주 사용.
Layout 역할의 컴포넌트로 이해 가능. composition(합성) 개념 기반 구조.
Header, Footer, Page를 조합하여 공통 레이아웃 구성.
// src/shared/Layout.js
import React from 'react';
const HeaderStyles = {
width: '100%',
background: 'black',
height: '50px',
display: 'flex',
alignItems: 'center',
paddingLeft: '20px',
color: 'white',
fontWeight: '600',
};
const FooterStyles = {
width: '100%',
height: '50px',
display: 'flex',
background: 'black',
color: 'white',
alignItems: 'center',
justifyContent: 'center',
fontSize: '12px',
};
const layoutStyles = {
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
minHeight: '90vh',
}
function Header() {
return (
<div style={{ ...HeaderStyles }}>
<span>Sparta Coding Club - Let's learn React</span>
</div>
);
}
function Footer() {
return (
<div style={{ ...FooterStyles }}>
<span>copyright @SCC</span>
</div>
);
}
function Layout({ children }) {
return (
<div>
<Header />
<div style={{...layoutStyles}}>
{children}
</div>
<Footer />
</div>
);
}
export default Layout;
// src/shared/Router.js
import React from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Home from '../pages/Home';
import About from '../pages/About';
import Contact from '../pages/Contact';
import Works from '../pages/Works';
import Layout from './Layout';
const Router = () => {
return (
<BrowserRouter>
{/* Layout으로 Routes 감쌈 */}
<Layout>
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
<Route path="works" element={<Works />} />
</Routes>
</Layout>
</BrowserRouter>
);
};
export default Router;
공통 UI 유지하면서 페이지별 내용만 교체 가능.
레이아웃 재사용에 적합한 구조.
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="about" element={<About />} />
</Route>
</Routes>
라우트마다 다른 레이아웃 적용 가능.
동적이고 유연한 라우트 관리를 제공.
<Layout>
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
</Routes>
</Layout>
모든 페이지에 동일한 레이아웃 적용 시 적합.
구조가 단순해서 관리에 용이.