/courses
의 하위 페이지로 /courses/react-frontend-development
등 여러 페이지가 있을 때 해당 페이지들을 따로 묶어줄 수 있다.
<Route path ="courses">
</Route>
사이에 관련 페이지를 모두 넣고,<Route path="/courses" element={<CourseListPage />} />
) 에서 path를 index로 바꿔준다.import { BrowserRouter, Routes, Route } from "react-router-dom";
import App from "./components/App";
import CourseListPage from "./pages/CourseListPage";
import CoursePage from "./pages/CoursePage";
function Main() {
return (
<BrowserRouter>
<App>
<Routes>
<Route path="/" element={<HomePage />} />
{/* courses 의 하위 경로를 만들고 싶을 때 Route로 다시 감싼다. */}
<Route path="courses">
<Route index element={<CourseListPage />} />
<Route path="react-frontend-development" element={<CoursePage />} />
</Route>
</Routes>
</App>
</BrowserRouter>
);
}
부모 Route 컴포넌트에 element 를 지정하고,
Outlet 이라는 컴포넌트를 활용하면 공통된 레이아웃을 지정해줄 수 있다.
위 코드에서 모든 컴포넌츠들은 <App>
</App>
컴포넌츠 사이에 하위 컴포넌츠로 들어있다.
App 컴포넌츠에서는 하위 컴포넌츠를 { children }
props로 받아 <Nav />
와 <Footer />
사이에 렌더링 한다.
// App.js
import Nav from "../components/Nav";
import Footer from "../components/Footer";
function App({children}) {
return (
<>
<Nav />
<div >
{children}
</div>
<Footer />
</>
);
}
{children} props로 전달되는 하위 컴포넌츠들을 <Outlet />
컴포넌츠로 바꾸면 App 컴포넌츠의 레이아웃(네비 - 컴포넌츠 - 푸터)을
하위 컴포넌츠들에 공통적으로 지정해줄 수 있다.
<App>
컴포넌츠를 바로 <Routes>
안에 넣으면 오류가 난다. <Route element={<App />}>
로 감싸주고 모든 하위 경로를 나타낼 것이므로 path="/" 를 추가해준다.<Homepage>
컴포넌츠의 path를 index로 바꿔준다.// main.js
import { BrowserRouter, Routes, Route } from "react-router-dom";
import App from "./components/App";
import HomePage from "./pages/HomePage";
import CourseListPage from "./pages/CourseListPage";
import CoursePage from "./pages/CoursePage";
function Main() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<App />}>
<Route index element={<HomePage />} />
<Route path="courses">
<Route index element={<CourseListPage />} />
<Route path="react-frontend-development" element={<CoursePage />} />
</Route>
</Route>
</Routes>
</BrowserRouter>
);
}
<Outlet>
을 사용한다.import { Outlet } from "react-router-dom";
function App() {
return (
<>
<Nav className={styles.nav} />
<div className={styles.body}>
<Outlet />
</div>
<Footer className={styles.footer} />
</>
);
}
파라미터(parameter): 경로에서 사용하는 동적인 값
params : 파라미터들을 모아놓은 것
URL에서 /courses
의 하위 경로로 /courses/react
, /courses/javascript
, ... 등 여러 개의 파라미터가 있을 수 있다.
동적으로 변하는 parameter 경로들에 대해 보여줄 모든 페이지들을<Route path="">
로 하드 코딩하는 것은 매우 번거로운 일이다.
따라서 경로를 고정적인 값이 아닌 달라지는 동적 경로(parameter)로 정해줄 때 :
를 앞에 붙이고 이름을 지정해준다.
// main.js
// 바꾸기 전
// courses 경로(path)의 모든 하위 경로(parameter)에 보여줄 컴포넌츠만 지정되어 있다.
<Route path="courses">
<Route index element={<CourseListPage />} />
<Route path="react-frontend-development" element={<CoursePage />} />
<Route path="javascript-intermediate" element={<CoursePage />} />
// parameter의 수만큼 반복해야함
</Route>
// 바꾼 후
// courses 경로(path) 의 하위 경로(parameter)로 여러 courseSlug 값들이 올 수 있다.
<Route path=":courseSlug" element={<CoursePage />} />
useParams()
는 현재 URL에서<Route path="경로">
와 일치하는 key/value 가 들어있는 객체를 반환한다.
🔗 ReactRouter 공식홈페이지 : useParams❊ 참고로 parameter가 아닌 현재 페이지의 pathname을 가져오려면 useLocation()을 사용해야 한다.
useParams 가 리턴하는 객체에는 현재 경로의 parameter 가 저장되어 있다.
<Route />
에서 동적 경로로 지정한 경로는 페이지 경로가 달라질 때마다 useParams()에서 리턴하는 파라미터 값도 달라진다.
따라서 하나의 컴포넌츠(CoursePage.js)를 가지고 parameter에 따라 달라진 데이터를 받아서 서로 다른 페이지처럼 보여줄 수 있다.
// CoursePage.js
import { useParams } from "react-router-dom";
function CoursePage() {
const { courseSlug } = useParams(); // 현재 경로(파라미터들)를 객체로 리턴
// 현재 URL의 파라미터(경로)가 { courseSlug: "경로"}로 리턴된다.
{/* 바꾸기 전 :
const course = getCourseBySlug('react-frontend-development');
하나의 경로에서만 course 객체가 리턴되었음*/}
const course = getCourseBySlug(courseSlug); // courseSlug 값에 따라 course 데이터 객체를 리턴 함수
const courseColor = getCourseColor(course?.code);
{/* 하기 내용 함수 생략 */}
return (
<>
{/* 데이터 course.title, course.content 로 화면 구성 */}
</>
);
}