npm install react-router-dom
createBrowserRouter : 이 어플리케이션에서 지원하려는 라우트를 정의한다. 해당 함수 안에 라우터 정의 객체로 된 배열을 넣고, 모든 객체들은 각각 하나의 라우트를 가리킨다.path : 경로 지정element : 요소를 정의 -> 해당 경로가 활성화되면 element에서 작성한 JSX코드가 연결createBrowserRouter에서 리턴된 값을 변수나 상수에 저장.RouterProvider : 이 컴포넌트는 우리의 JSX 코드에서 사용할 수 있는 일반 컴포넌트import { createBrowserRouter, RouterProvider } from "react-router-dom";
import HomePage from "./pages/Home";
const router = createBrowserRouter([
{ path: "/", element: <HomePage /> }, // 메인.
]);
function App() {
return <RouterProvider router={router} />;
}
export default App;
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import HomePage from "./pages/Home";
import ProductsPage from "./pages/Products";
const router = createBrowserRouter([
{ path: "/", element: <HomePage /> },
{ path: "/products", element: <ProductsPage /> },
]);
function App() {
return <RouterProvider router={router} />;
}
export default App;

import {
createBrowserRouter,
createRoutesFromElements,
Route,
RouterProvider,
} from "react-router-dom";
import HomePage from "./pages/Home";
import ProductsPage from "./pages/Products";
const routeDefinitions = createRoutesFromElements(
<Route>
<Route path="/" element={<HomePage />} />
<Route path="/products" element={<ProductsPage />} />
</Route>
);
// const router = createBrowserRouter([
// { path: "/", element: <HomePage /> },
// { path: "/products", element: <ProductsPage /> },
// ]);
const router = createBrowserRouter(routeDefinitions);
function App() {
return <RouterProvider router={router} />;
}
export default App;
import { Link } from "react-router-dom";
function HomePage() {
return (
<>
<h1>My Home Page</h1>
<p>
Go to <Link to="/products">the list of products</Link>
</p>
</>
);
}
export default HomePage;
<a>) 요소를 렌더링하게 되지만 기본적으로는 그 요소에 대한 클릭을 감시.
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import HomePage from "./pages/Home";
import ProductsPage from "./pages/Products";
import RootLayout from "./pages/Root";
const router = createBrowserRouter([
{
path: "/",
element: <RootLayout />,
children: [
{ path: "/", element: <HomePage /> },
{ path: "/products", element: <ProductsPage /> },
],
},
]);
function App() {
return <RouterProvider router={router} />;
}
export default App;
import { Link } from "react-router-dom";
function MainNavigaton() {
return (
<header>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/products">Products</Link>
</li>
</ul>
</nav>
</header>
);
}
export default MainNavigaton;
import MainNavigaton from "../components/MainNavigation";
import { Outlet } from "react-router-dom";
// Outlet : 이 컴포넌트는 자녀 라우트 요소들이 렌더링되어야 할 장소를 표시하는 역할을 한다.
function RootLayout() {
return (
<>
<MainNavigaton />
<Outlet />
</>
);
}
export default RootLayout;

import MainNavigaton from "../components/MainNavigation";
function ErrorPage() {
return (
<>
<MainNavigaton />
<main>
<h1>오류가 발생했습니다!</h1>
<p>페이지를 찾을 수 없습니다!</p>
</main>
</>
);
}
export default ErrorPage;
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import HomePage from "./pages/Home";
import ProductsPage from "./pages/Products";
import RootLayout from "./pages/Root";
import ErrorPage from "./pages/Error";
const router = createBrowserRouter([
{
path: "/",
element: <RootLayout />,
errorElement: <ErrorPage />, // 에러 페이지
children: [
{ path: "/", element: <HomePage /> },
{ path: "/products", element: <ProductsPage /> },
],
},
]);
function App() {
return <RouterProvider router={router} />;
}
export default App;

활성화된 링크를 강조하기
NavLink는 Link와 똑같이 사용하지만 특수한 동작이 있다.
className 프로퍼티를 추가하면 그 함수는 앵커 태그에 추가되어야 하는 CSS 클래스 네임을 리턴할 것이다.기본적으로 NavLink는 실제로 현재 활성인 라우트의 경로가 NavLink의 경로로 시작하는지 확인한다. 이 프로젝트에서는 '/' 라우트에서 동작하게 된다. → 이는 모든 라우트에서 활성화되는 것이다. 따라서 react-router-dom은 end 프로퍼티도 제공한다.
end : 현재 활성인 라우트의 URL 뒤가 해당 경로로 끝나면, 해당 링크를 활성화했음을 간주한다는 의미..
import { NavLink } from "react-router-dom";
import classes from "./MainNavigation.module.css";
function MainNavigaton() {
return (
<header className={classes.header}>
<nav>
<ul className={classes.list}>
<li>
<NavLink
to="/"
className={({ isActive }) =>
isActive ? classes.active : undefined
}
style={({ isActive }) => ({
textAlign: isActive ? "center" : "left",
})}
end
>
Home
</NavLink>
</li>
<li>
<NavLink
to="/products"
className={({ isActive }) =>
isActive ? classes.active : undefined
}
>
Products
</NavLink>
</li>
</ul>
</nav>
</header>
);
}
export default MainNavigaton;
end를 넣을 필요가 없다. 왜냐하면 현재까지 '/products'로 끝나는 페이지가 더 없기 때문이다! → 유일한 페이지end를 넣어야만 한다 왜냐하면 '/'는 대부분의 페이지에서 거의 다 쓰이고 있기 때문이다.import { Link, useNavigate } from "react-router-dom";
function HomePage() {
const navigate = useNavigate();
function navigateHandler() {
navigate("/products");
}
return (
<>
<h1>My Home Page</h1>
<p>
Go to <Link to="/products">the list of products</Link>
</p>
<p>
<button onClick={navigateHandler}>Navigate</button>
</p>
</>
);
}
export default HomePage;
useNavigate: 네비게이션 동작을 트리거할 수 있다. 즉, 코드 안에서 다른 라우트로 전환 가능.:productId와 같은 동적 세그먼트 추가import { createBrowserRouter, RouterProvider } from "react-router-dom";
import HomePage from "./pages/Home";
import ProductsPage from "./pages/Products";
import RootLayout from "./pages/Root";
import ErrorPage from "./pages/Error";
import ProductDetailPage from "./pages/ProductDetail";
const router = createBrowserRouter([
{
path: "/",
element: <RootLayout />,
errorElement: <ErrorPage />,
children: [
{ path: "/", element: <HomePage /> },
{ path: "/products", element: <ProductsPage /> },
{ path: "/products/:productId", element: <ProductDetailPage /> },
],
},
]);
function App() {
return <RouterProvider router={router} />;
}
export default App;
import { useParams } from "react-router-dom";
function ProductDetailPage() {
const params = useParams();
// params 객체는 우리가 라우트 정의에서 프로퍼티로 정의한 모든 역동적인 경로 세그먼트가 담긴 간단한 자바스크립트 객체이다.
return (
<>
<h1> ProductDetailPage </h1>
<p>{params.productId}</p>
{/* '/products/:productId' */}
</>
);
}
export default ProductDetailPage;

import { Link } from "react-router-dom";
const PRODUCTS = [
{ id: "p1", title: "Product 1" },
{ id: "p2", title: "Product 2" },
{ id: "p3", title: "Product 3" },
];
function ProductsPage() {
return (
<>
<h1>the Products Page</h1>
<ul>
{PRODUCTS.map((product) => (
<li key={product.id}>
<Link to={`/products/${product.id}`}>{product.title}</Link>
</li>
))}
</ul>
</>
);
}
export default ProductsPage;

import { createBrowserRouter, RouterProvider } from "react-router-dom";
import HomePage from "./pages/Home";
import ProductsPage from "./pages/Products";
import RootLayout from "./pages/Root";
import ErrorPage from "./pages/Error";
import ProductDetailPage from "./pages/ProductDetail";
const router = createBrowserRouter([
{
path: "/root",
element: <RootLayout />,
errorElement: <ErrorPage />,
children: [
{ path: "", element: <HomePage /> },
{ path: "products", element: <ProductsPage /> },
{ path: "products/:productId", element: <ProductDetailPage /> },
],
},
]);
function App() {
return <RouterProvider router={router} />;
}
export default App;
/root, /root/products, /root/products/p1로 접근이 가능하다.Link, NavLink의 to 프로퍼티에도 적용이 된다.Link 컴포넌트를 사용할 때 특수한 relative 프로퍼티 추가할 수 있고 이것은 path 또는 route 중에 하나로 설정 가능하다.import { Link } from "react-router-dom";
const PRODUCTS = [
{ id: "p1", title: "Product 1" },
{ id: "p2", title: "Product 2" },
{ id: "p3", title: "Product 3" },
];
function ProductsPage() {
return (
<>
<h1>the Products Page</h1>
<ul>
{PRODUCTS.map((product) => (
<li key={product.id}>
<Link to={product.id}>{product.title}</Link>
</li>
))}
</ul>
</>
);
}
export default ProductsPage;
import { useParams, Link } from "react-router-dom";
function ProductDetailPage() {
const params = useParams();
// params 객체는 우리가 라우트 정의에서 프로퍼티로 정의한 모든 역동적인 경로 세그먼트가 담긴 간단한 자바스크립트 객체이다.
return (
<>
<h1> ProductDetailPage </h1>
<p>{params.productId}</p>
{/* '/products/:productId' */}
<p>
<Link to="..">Back</Link>
</p>
</>
);
}
export default ProductDetailPage;
/root/products/p1에서 Back 버튼을 누르면 다시 /root로 돌아옴을 알 수 있다./root이고 자녀 라우트로 3개가 있는데, 이때 products와 products/:productId는 형제 라우트이다. 따라서 라우트를 기준으로 <Link to="..">을 하면 부모 라우트로 가는 것이다./root/products/p1 → /root/producst로 가고 싶기 때문에 다음과 같이 설정한다.import { useParams, Link } from "react-router-dom";
function ProductDetailPage() {
const params = useParams();
return (
<>
<h1> ProductDetailPage </h1>
<p>{params.productId}</p>
<p>
<Link to=".." relative="path">
Back
</Link>
</p>
</>
);
}
export default ProductDetailPage;
relative="path"를 함으로써 Back 버튼을 눌렀을 때 /root/products/p1→/root/products로 갈 수 있게 된다.
index 특수 프로퍼티를 추가하면, 해당 라우트가 소위 인덱스 라우트로 변하게 된다. → 부모 라우트가 현재 활성화되면 표시되어야 하는 기본 라우트라는 의미이다.import { createBrowserRouter, RouterProvider } from "react-router-dom";
import HomePage from "./pages/Home";
import ProductsPage from "./pages/Products";
import RootLayout from "./pages/Root";
import ErrorPage from "./pages/Error";
import ProductDetailPage from "./pages/ProductDetail";
const router = createBrowserRouter([
{
path: "/",
element: <RootLayout />,
errorElement: <ErrorPage />,
children: [
{ index: true, element: <HomePage /> },
{ path: "products", element: <ProductsPage /> },
{ path: "products/:productId", element: <ProductDetailPage /> },
],
},
]);
function App() {
return <RouterProvider router={router} />;
}
export default App;