ํด๋น ๊ฒ์๊ธ์ React Router์ ๊ณต์ ๋ฌธ์ ๋ฐ Youtube๋ฅผ ๊ณต๋ถํ ํ ๋๋ก ์์ฑ๋์์ต๋๋ค. ํน์๋ผ๋ ์๋ชป๋ ๋ถ๋ถ์ด ์๋ ๊ฒฝ์ฐ ๊ผญ ๋๊ธ์ ๋จ๊ฒจ์ฃผ์ธ์ ๐โโ๏ธ ๐โโ๏ธ
npm install react-router-dom@6
<BrowserRouter>
-<BrowserRouter>
๋ ์น ๋ธ๋ผ์ฐ์ ์ ์ฌ์ฉ๋๋ค.
<BrowserRouter>
๋ History API ์ฒ๋ผ ์น ์ ํ๋ฆฌ์ผ์ด์
์์ ํ์ด์ง๋ฅผ ์๋ก๊ณ ์นจํ์ง ์๊ณ ๋ ์ฃผ์๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ ์ญํ <BrowserRouter>
navigates using the browser's built-in history stack.<Routes>
and <Route>
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
<Route path="expenses" element={<Expenses />} />
<Route path="invoices" element={<Invoices />} />
</Routes>
</BrowserRouter>
<Route>
๋ if
๋ฌธ๊ณผ ๋น์ทํ๋ค๊ณ ์๊ฐํ๋ฉด๋๋ค. ๋ง์ฝ์ path๊ฐ ํด๋น URL์ ๊ฐ๋ฆฌํจ๋ค๋ฉด ํด๋น path์ element
๋ฅผ ๋ ๋๋ง ํ๊ฒ ๋๋ค.<Routes>
๋ ์์ ์ ๋ชจ๋ children
์ ํ์ธํด๋ณธ ํ ํด๋น๋๋ <Route>
์๋ฆฌ๋จผํธ๋ฅผ ๋ ๋๋ง ํ๋ค.<Link>
import { Link } from "react-router-dom";
function Home() {
return (
<div>
<h1>Home</h1>
<nav>
<Link to="/">Home</Link> |{" "}
<Link to="about">About</Link>
</nav>
</div>
);
a
ํ๊ทธ๋ฅผ ํ์ด์ง ์ด๋์์ด ํ์ด์ง๋ฅผ ๋ณํํ๋๋ก ํด์ค<NavLink>
import * as React from "react";
import { NavLink } from "react-router-dom";
function NavList() {
// This styling will be applied to a <NavLink> when the
// route that it links to is currently selected.
let activeStyle = {
textDecoration: "underline"
};
let activeClassName = "underline"
return (
<nav>
<ul>
<li>
<NavLink
to="messages"
style={({ isActive }) =>
isActive ? activeStyle : undefined
}
>
Messages
</NavLink>
</li>
<li>
<NavLink
to="tasks"
className={({ isActive }) =>
isActive ? activeClassName : undefined
}
>
Tasks
</NavLink>
</li>
</ul>
</nav>
);
}
<Link>
ํ๊ทธ์ ๊ฒฐ์ด ๊ฐ์. ๋ค๋ง, <NavLink>
์ ๊ฒฝ์ฐ ๋ณธ์ธ์ด activeํ์ง ์ํ์ง ๊ตฌ๋ณํ ์ ์์!<NavLink>
์ฌ์ฉ ์ isActive
๋ผ๋ ๊ฐ์ผ๋ก activeํ์ง ์ํ์ง ๊ตฌ๋ณํ ์ ์์ <BrowserRouter>
<Routes>
<Route path="/" element={<App />}>
<Route path="expenses" element={<Expenses />} />
<Route path="invoices" element={<Invoices />} />
</Route>
</Routes>
</BrowserRouter>,
expenses
ํ์ด์ง๋ก ์ด๋ ์ URL์ ๊ฒฝ์ฐ /
+ expenses
/
์ path๋ฅผ ๊ฐ์ง ๋ถ๋ชจ ๋ผ์ฐํธ๋ฅผ ๊ฐ์ง App์ ์ปดํฌ๋ํธ๋ ๊ณตํต์ผ๋ก ์ฌ์ฉ๋๋ฉด์ ์์ ์ปดํฌ๋ํธ์ธ Expenses์ Invoices๋ง ๋ณ๊ฒฝ๋๋ค ๐ ์ด๊ฒ ๊ฐ๋ฅํ๋๋ก ํ๋ ค๋ฉด ํ๋จ์ <Outlet/>
๊ฐ๋
์ ์์์ผ ํจ.<Outlet>
export default function App() {
return (
<div>
<h1>Bookkeeper</h1>
<nav
style={{
borderBottom: "solid 1px",
paddingBottom: "1rem"
}}
>
<Link to="/invoices">Invoices</Link> |{" "}
<Link to="/expenses">Expenses</Link>
</nav>
<Outlet />
</div>
);
}
<Outlet/>
์ ์ ์ด์ค๋ค. <Outlet/>
์ ๋ ์์์ path๋ณ๋ก ๋ฐ๊ฟ์ฃผ๋ ์ญํ ์ ํ๋ค.<Outlet/>
์ ์์ path์ ์ปดํฌ๋ํธ ์์ญ์ ๋งํฌํ๋ ๊ตฌ๊ฐ์ด๋ผ ์๊ฐํ๋ฉด ๋๋ค!path="*"
function App() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="dashboard" element={<Dashboard />} />
<Route path="*" element={<NotFound />} />
</Routes>
);
}
<Route path="invoices" element={<Invoices />}>
<Route index element={<InvoiceBase/>}/> ๐ฉ
<Route path=":invoiceId" element={<Invoice />} />
</Route>
<Route/>
์ path ๋์ index
๋ผ๋ prop์ด ๋ค์ด๊ฐ์๋ค. useNavigate
๐ v5์์๋ useHistory
์๋ค๊ฐ ๋ช
์นญ์ด ๋ณ๊ฒฝ๋จ.
useHistory
๋ฅผ ์ด์ฉํ ์ ์๋คimport { useNavigate } from "react-router-dom";
function SignupForm() {
let navigate = useNavigate();
async function handleSubmit(event) {
event.preventDefault();
await submitForm(event.target);
navigate("../success", { replace: true });
}
return <form onSubmit={handleSubmit}>{/* ... */}</form>;
}
navigate(-1)
์ฒ๋ผ ์
๋ ฅ๊ฐ๋ฅ:style
๊ณผ useParams
import { Routes, Route, useParams } from "react-router-dom";
function App() {
return (
<Routes>
// 2๏ธโฃ 1๋ฒ์์ ๋ฐ์ ๊ฐ์ param์ด ๋๋ค.
// `:`ํค์๋ ์ฌ์ฉํ์ฌ param์ด ์๋ค๊ณ ์๋ ค์ค.
<Route path="invoices" element={<BlogList />}>
<Route path=":id" element={<BlogDetails />} />
</Route>
</Routes>
);
}
function BlogDetails() {
// 3๏ธโฃ ํ๋จ ๋ฌธ๊ตฌ๋ฅผ ํตํด id๋ฅผ Route์์ ๋ฐ์์ด.
let { id } = useParams();
return <h1>Blog {id}</h1>;
}
const BlogList = ({ blogs }) => {
return (
<div className="blog-list">
<h2>All Blogs ๐</h2>
{blogs.map((blog) => (
<div className="blog-preview" key={blog.id}>
// 1๏ธโฃ ์ด๊ณณ์์ param์ ์ด๋ค ๊ฐ์ด ๋ค์ด๊ฐ๋ ์ง ์ค์ .
<Link to={`/blogs/${blog.id}`}>
<h3>{blog.title}</h3>
<p> Written By {blog.author} </p>
</Link>
</div>
))}
<Outlet />
</div>
);
};
:
ํค์๋ ์ฌ์ฉuseParams
ํ
์ ์ฌ์ฉํด์ ๋ผ์ฐํธ์์ ์ค์ ํ params๋ฅผ ๋ฐ์์ด.import { useParams } from "react-router-dom";
export default function Invoice() {
let params = useParams();
return <h2>Invoice: {params.invoiceId}</h2>;
}
useSearchParams
/
๋ฅผ ์ฌ์ฉํ์ง๋ง, search params์ ๊ฒฝ์ฐ ?
๋ฅผ ์ฌ์ฉํจ "/login?success=1"
useRoutes
<Routes>
์ <Route>
๋์ ์ฌ์ฉ<Routes>
<Route>
elementsimport * as React from "react";
import { useRoutes } from "react-router-dom";
function App() {
let element = useRoutes([
{
path: "/",
element: <Dashboard />,
children: [
{
path: "messages",
element: <DashboardMessages />
},
{ path: "tasks", element: <DashboardTasks /> }
]
},
{ path: "team", element: <AboutPage /> }
]);
return element;
}