์ฃผ์์ ๋ฐ๋ผ ๊ทธ์ ๋ง๋ ์ปดํฌ๋ํธ๋ฅผ ๋ก๋ฉ์๊ฐ์ ๋จ์ถํ์ฌ ๋ณด์ฌ์ค ์ ์๋ ๋ฆฌ์กํธ ๋ผ์ฐํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค.
- ๋ผ์ฐํ : ๋ค๋ฅธ ์ฃผ์์ ๋ค๋ฅธ ํ๋ฉด์ ๋ณด์ฌ ์ฃผ๋ ๊ฒ
๊ธฐ์กด์๋ HTML๋ฌธ์๋ ํ
ํ๋ฆฟ ์์ง์ ์ฌ์ฉํ์ฌ ๊ฒฝ๋ก์ ๋ง๋ ๋ฌธ์๋ฅผ ํ ๋นํด์ฃผ์๋ค.
์๋ก์ด ๊ฒฝ๋ก์ ๋ค์ด๊ฐ ๋๋ง๋ค ์๋ฒ์์ HTML์ ๋ฐ์ดํฐ๋ค์ ๋ถ๋ฌ์์ผํ๋ค.
์ด๋ ๋ง์ ์ฌ์ฉ์๊ฐ ๋ชฐ๋ฆฌ๊ฒ ๋๋ฉด ์๋ฒ์ ๊ณผ๋ถํ๋ฅผ ์ผ์ผํฌ ์ ์๊ณ ์ธํฐ๋ ์ ์ด ๋ง์ ์น์ด๋ผ๋ฉด ์ํ์ ์ง ์ด๋ ค์ ๋ฐ ๋ก๋ฉ์ ์๊ฐ์ด ๊ฑธ๋ฆด ์ ์๋ค๋ ๋จ์ ์ด ์๋ค.
์ด๋ฌํ ๋จ์ ์ ๋ณด์ํ๊ธฐ์ํด ๋ฆฌ์กํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ทฐ ๋ ๋๋ง์ ๋ธ๋ผ์ฐ์ ๊ฐ ๋ด๋นํ์ฌ ๊ฒฝ๋ก์ ๋ฐ๋ฅธ ์ปดํฌ๋ํธ๋ฅผ ํ์ํ ๋๋ง๋ค ๋ถ๋ฌ์ ๋ณด์ฌ์ค๋ค.
์ด๋ฌํ ๋ฐฉ๋ฒ์ ๊ฒฝ๋ก์ด๋์ ํ์ฌ๋ ๋๊น์์ด ํ๋ฉด์ ํ์ ํ ์ ์์ด ๋ก๋ฉ์๊ฐ์ ์ค์ผ ์ ์๋ค๋ ๊ฐ์ ์ด ์๋ค.
ํ์ง๋ง ๋ชจ๋ ๋ทฐ๋ฅผ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ , ์ฆ ์ปดํฌ๋ํธ๋ก ๋ถ๋ฌ์์ผํ๋ค๋ ์ ์์ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ด ๋งค์ฐ ์ปค์ง๋ค๋ ๋จ์ ์ด ์๋ค.
์ด๋ ํ์ด์ง ๋ก๋ฉ์ ์ฌ์ฉ์๊ฐ ์ค์ ๋ก ๋ฐฉ๋ฌธํ์ง์์ ์คํฌ๋ฆฝํธํ์ผ๋ ๋ถ๋ฌ์์ง ์ ์๊ฒ ๋๋ค.
์ด๋ฌํ ๋จ์ ์ ์ถํ ์ฝ๋์คํ๋ฆฌํ ์ด๋ผ๋ ๋ฐฉ๋ฒ์ ์ด์ฉํ์ฌ ๋ก๋ฉ์๋๋ฅผ ๊ฐ์ ํ ์ ์๋ค.
์ ๋ฆฌํ์๋ฉด react router๋ ๋ผ์ฐํ ์ ๋ณด๋ค ๊ฐํธํ๊ฒ ๊ตฌํํด์ค์ ์๋ ๋ฆฌ์กํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค.
react router๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๋ฆฌ์กํธ ํ๋ก์ ํธ์์ ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ react์ ๋ณ๊ฐ๋ก ์ค์นํด์ค์ผํ๋ค.
npm i react-router-dom
react router ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํฌ๊ฒ 2๊ฐ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ค.
- react router : react router์ ํต์ฌ ๊ธฐ๋ฅ์ ๋ด๊ณ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค. ๋ผ์ฐํ , ํต์ฌ ์ปดํฌ๋ํธ, ํ ๋ฑ์ ์ฌ์ฉํ ์ ์๋ค.
- react router dom: react router ๊ธฐ๋ฅ์ ๋ชจ๋ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ ์ถ๊ฐ๋ก DOM API๊ธฐ๋ฅ์ด ์๋ค.(BroswerRouter, HasgRouter , Link)
react router ๋ผ์ด๋ธ๋ฌ๋ฆฌ์๋ ์ฌ๋ฌ์ญํ ์ ํ๋ ํ๊ทธ๊ฐ ์๋ค.
๊ฐ ํ๊ทธ๊ฐ ์ด๋ค ์ญํ ์ ํ๋์ง ์์๋ณด๊ฒ ๋ค.
BrowserRouter๋ ์ต์๋จ ์ปดํฌ๋ํธ์ ๊ฐ์ธ์ค์ผํ๋ ํ๊ทธ์ด๋ค.
์น ๋ธ๋ผ์ฐ์ ์์ react router ๊ตฌํํ ํ๊ฒฝ ์ปจํ ์คํธ๋ฅผ ์ ๊ณตํ๋ค.
History API๋ฅผ ์ด์ฉํ์ฌ ์๋ฒ์ ์์ฒญ์์ด ๊ฒฝ๋ก์ด๋์ ํ๊ฒ ํด์ฃผ๊ณ ํ์ฌ ์ฃผ์์ ๊ด๋ จ๋ ์ ๋ณด๋ฅผ ์ ์ฅํด์ค๋ค.
์ด๋ ์๋ก๊ณ ์นจ์์ด ํ์ด์ง์ด๋์ ํ๊ฒ ํด์ฃผ๋ฉฐ, ํ์ฌ ์ฃผ์์ ๊ด๋ จ๋ ์ ๋ณด๋ฅผ props๋ก ์ฝ๊ฒ ์กฐํํ๊ฑฐ๋ ์ฌ์ฉํ๊ฒ ํด์ค๋ค.
History API
์๋ฒ์๊ฒ ์์ฒญ์์ด ํ์ด์ง์ ํ ๋ฐ ๋ค๋ก๊ฐ๊ธฐ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํด์ฃผ๋ Web API
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById("root")
);
<Route path ="/about" element = {<About/>}/>
<Route path ="/contact" element = {<Contact/>}/>
๊ฒฝ๋ก์ ๋ง๋ ์ฃผ์๋ฅผ ์ ๋ ฅํด์ฃผ๋ฉด element attribute์ ํ ๋นํ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋๋ค.
๋ณธ ์ฃผ์๊ฐ http://localhost:3000์ด๋ผ ํ์์ ๋ http://localhost:3000/about๋ก ์ด๋ํ๋ค๋ฉด About์ปดํฌ๋ํธ๋ฅผ ๋ณด์ฌ์ค๋ค.
react router version 6๋ถํฐ๋ Route๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ Routes๋ก ๊ฐ์ธ์ค์ผํ๋ค.
(์ด์ version์์๋ ๊ฐ์ธ์ค ํ์๊ฐ ์์์.)
Route๋ค์ ๋ด์๋๋ ํ๊ทธ์ด๋ค.
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Routes>
Linkํ๊ทธ๋ history API๋ก ๊ธฐ๋ฐ์ผ๋ก ๊ฐ์ธ์ง aํ๊ทธ์ ๊ฐ๋ค.
Link๋ ์ฌ์ฉ์๊ฐ ํด๋ฆญํจ์ผ๋ก์จ ํด๋น ๊ฒฝ๋ก์ ๋ฐ๋ฅธ ํ์ด์ง๋ก ์ด๋ํ ์ ์๋๋ก ํ๊ฒ ํ๋ ํ๊ทธ์ด๋ค.
(aํ๊ทธ์ ์ ์ฌ)
ํ์ด์ง ์ ํ ๋ฐฉ์ง ๊ธฐ๋ฅ์ด ๋ด์ฅ๋์ด์๋ค.
aํ๊ทธ์ Linkํ๊ทธ์ ์ฐจ์ด์
a ํ๊ทธ๋ ํ์ด์ง๊ฐ ์ ํ๋๋ ๊ณผ์ ์์ ํ์ด์ง๋ฅผ ์๋ก ๋ถ๋ฌ์ค๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด์ ๋ ๋๋ง๋์๋ ๊ฒ๋ค์ด ๋ค ๋ ๋ผ๊ฐ๊ฒ ๋๋ค.
ํ์ง๋ง Linkํ๊ทธ๋ History API๋ฅผ ์ด์ฉํ์ฌ ์๋ฒ์๊ฒ ์์ฒญํ์ง์๊ณ ๋ธ๋ผ์ฐ์ ๋ด์์ ํด๊ฒฐํด ํ์ด์ง์ ์ฃผ์๋ง ๋ณ๊ฒฝํด์ฃผ๋ ์ฅ์ ์ ๊ฐ์ง๊ณ ์๋ค.
๋ฐ๋ผ์ aํ๊ทธ๊ฐ ์๋ Linkํ๊ทธ๋ฅผ ์ฐ๋ ๊ฒ์ด ๋ ์ ์ ํ๋ค.
<Link to="/about">About</Link> // aboutํ์ด์ง๋ก ์ด๋
HashRouter์ ๋ช๋ช ์ด์ ๋ก url์ ์๋ฒ๋ก ์ ์กํ๋ คํ์ง ์์ ๋ ์ฌ์ฉํ๋ค.
์ด๋ ์๋ฒ์ ์จ์ ํ ๋ชจ๋ ๊ฒ์ ์ ๋ดํ์ง ์๊ฒ ํ ๋ ์ฌ์ฉํ๋ค.
HashRouter๋ ์ฃผ์์ #์ ๋ถ์์ผ๋ก์จ ํ์ฌ ์ฃผ์์ ๊ด๋ จ๋ ์ ๋ณด๋ฅผ ์ ์ฅํ๊ฒ ํด์ค๋ค.
๊ทธ๋ฆฌ๊ณ ํด๋น url์ ์๋ฒ๋ก ๋ณด๋ด์ง์ง์๋๋ค.
Router์ BrowserRouter,HashRouter,NativeRouter,StaticRouter ๋ฑ ๋ชจ๋ router component๋ค์ด ๊ณต์ ํ๋ low-level interface์ด๋ค.
์ฌ์ฉ ์ฉ๋์ ๋ง๊ฒ ์์ ๊ฐ์ high-level routers๋ค์ด ๋ง๋ค์ด์ก๊ธฐ ๋๋ฌธ์ router์ ์ง์ ์ ์ผ๋ก ์ธ ์ผ์ ๊ฑฐ์ ์๋ค.
๋๋ฌธ์ ์์ ์ ํ๊ฒฝ์ ๋ฐ๋ผ ๋ง๋ high-level router๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
ํน๋ณํ Linkํ๊ทธ๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.
NavLink๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒฝ์ฐ๋ ์ฌ๋ฌ ๊ฒฝ์ฐ๊ฐ ์์ง๋ง ๋ํ์ ์ธ ์๋ก Navigation Menu์์ ์นดํ
๊ณ ๋ฆฌ๊ฐ ์ ํ๋ฌ์ ๋์ ํ์๋๊ฒ ํ๋ ๊ธฐ๋ฅ์ ์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค.
<NavLink
to="/"
style={({ isActive }) => (isActive ? { color: "red" } : null)}
>
Home
</NavLink>
|
<NavLink
to="about"
style={({ isActive }) => (isActive ? { color: "red" } : null)}
>
About
</NavLink>
|
<NavLink
to="contact"
style={({ isActive }) => (isActive ? { color: "red" } : null)}
>
Contact
</NavLink>
<Routes>
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
</Routes>
NavLink๋ง๋ค ์์ ๊ฐ์ด style์์ฑ์ ์ ๋ ฅํด์ฃผ๊ธฐ ๋ฒ๊ฑฐ๋กญ๋ค๋ฉด customizingํ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด์ค๋ค.
import React from "react";
import { NavLink } from "react-router-dom";
const ColorNavLink = (path, LinkName) => {
return (
<NavLink
to={path}
style={({ isActive }) => (isActive ? { color: "red" } : null)}
>
{LinkName}
</NavLink>
);
};
export default ColorNavLink;
import React from "react";
import { Route, Routes } from "react-router-dom";
import ColorNavLink from "./ColorNavLink";
import About from "./About";
import Contact from "./Contact";
const Home = () => {
return (
<div>
<h1>React Router Test Zone</h1>
{ColorNavLink("/", "Home")}|{ColorNavLink("about", "About")} |
{ColorNavLink("contact", "Contact")}
<h2>Welcome!</h2>
<Routes>
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
</Routes>
</div>
);
};
export default Home;
App.js
import React from "react";
import { Route, Routes } from "react-router-dom";
import Home from "./routes/Home";
import About from "./routes/About";
import Contact from "./routes/Contact";
const App = () => {
return (
<div>
<Routes>
<Route path="/" element={<Home />} />
<Route path="about/*" element={<About />} />
<Route path="contact" element={<Contact />} />
</Routes>
</div>
);
};
export default App;
์ ์๊ฒฝ๋ก
์๋๊ฒฝ๋ก
์๋ ๊ฒฝ๋ก์ ์ ์ํ์ ๋์ ์ฐ๋ฆฌ๋ ํฐ ํ๋ฉด์ ๋ณผ ์ ์๋ค.
ํฐ ํ๋ฉด์ด ์๋๋ผ ์๋ ๊ฒฝ๋ก์ ์ ์ํ๋ค๋ ๊ฒ์ ์๋ ค์ฃผ๊ธฐ ์ํด No match Route๋ฅผ ๊ตฌํํด๋ณด์.
App.js
import React from "react";
import { Route, Routes } from "react-router-dom";
import Home from "./routes/Home";
import About from "./routes/About";
import Contact from "./routes/Contact";
import NoMatch from "./routes/NoMatch";
const App = () => {
return (
<div>
<Routes>
<Route path="/" element={<Home />} />
<Route path="about/*" element={<About />} />
<Route path="contact" element={<Contact />} />
<Route path="/*" element={<NoMatch />} />
</Routes>
</div>
);
};
export default App;
NoMatch.js
import React from "react";
const NoMatch = () => {
return (
<div>
<h1>Not Found Page</h1>
<p>์๋ชป๋ ๊ฒฝ๋ก๋ก ๋ค์ด์ค์
จ์ต๋๋ค!</p>
</div>
);
};
export default NoMatch;
์๋ชป๋ ๊ฒฝ๋ก
๋ฐฉ๋ฒ์ ๊ฐ๋จํ๋ค.
Route๋ฅผ ํ๋ ๋ง๋ค์ด์ฃผ๊ณ path="/" ๋ผ๊ณ path prop์ ์ค์ ํด์ฃผ๋ฉด ๋๋ค.
"/"์ ์๋ฏธ๋ ๋์ ๊ธฐ๋ณธ๊ฒฝ๋ก๋ฅผ ์ ์ธํ ๋๋จธ์ง ํ์ ๊ฒฝ๋ก์ ํ ๋น๋ ์ปดํฌ๋ํธ(NoMatch)๋ฅผ ๋ณด์ฌ์ฃผ๊ฒ ๋ค๋ ์๋ฏธ์ด๋ค.
์ฆ, ๊ฒฝ๋ก์์ "๋ณ"์ ์๋ฏธ๋ "ํด๋น๊ฒฝ๋ก์ ๋ชจ๋ ํ์ ๊ฒฝ๋ก" ์ด๋ค.
NoMatch Route๋ง ๋ฐ๋ก ๊ตฌ๋ถํด์ฃผ๋ฉด ๋ชจ๋ ํ์ ๊ฒฝ๋ก์ NoMatch ์ปดํฌ๋ํธ๊ฐ ๋ณด์ฌ์ง ๊ฒ์ด๋ค.
ํ์ง๋ง Routes๋ผ๋ ์ปดํฌ๋ํธ๋ก Route๋ฅผ ๊ฐ์ธ์ฃผ๋ฉด ๊ฒฝ๋ก์ ๋ง๋ ์ปดํฌ๋ํธ๋ฅผ ์ฐ์ ์ ์ผ๋ก ๋ณด์ฌ์ค๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ /about์ด๋ /contact ๊ฒฝ๋ก์ ๋ค์ด๊ฐ๋ฉด NoMatch ์ปดํฌ๋ํธ๋ณด๋ค ๊ฒฝ๋ก๊ฐ ์ผ์นํ๋ About์ปดํฌ๋ํธ๋ Contact ์ปดํฌ๋ํธ๊ฐ ์ฐ์ ์ ์ผ๋ก ๋ณด์ฌ์ง๋ ๊ฒ์ด๋ค.
reference
This route will match any URL, but will have the weakest precedence so the router will only pick it if no other routes match.
by NoMatch Route
/*์ ์๋ฏธ : ๋ชจ๋ ๊ฒฝ๋ก์ ๊ธฐ๋ณธ์ ์ผ๋ก ํ ๋นํ ์ปดํฌ๋ํธ๋ฅผ ๋ณด์ฌ์ฃผ๊ฒ ๋ค.
๋ณ => ํด๋น ๊ฒฝ๋ก์ ๋ชจ๋ ํ์ ๊ฒฝ๋ก
์ ๋ฆฌ
NoMatch Route ๊ตฌํํ๋ ๋ฒ
1. Routes์์ NoMatch Route๋ฅผ ํ ๋นํด์ค๋ค.
- ์ด ๋ Routes์์๋ NoMatch Route๋ฟ๋ง ์๋ ๋ณด์ฌ์ ธ์ผํ ๋ค๋ฅธ Route๋ค๋ ๊ฐ์ด ๋ฃ์ด์ค๋ค.
- NoMatch Route์ ๊ฒฝ๋ก๋ path="/*"๋ก ์ค์ ํด์ค๋ค.
- ๊ธฐ๋ณธ ๊ฒฝ๋ก์ ๋ชจ๋ ํ์ ๊ฒฝ๋ก์ NoMatch ์ปดํฌ๋ํธ๋ฅผ ๋ณด์ฌ์ฃผ๊ฒ ๋ค.
(์ค์ ํ ๊ฒฝ๋ก๋ฅผ ์ ์ธํ๊ณ ๋)
์ฐ๋ฆฌ๊ฐ ํ์ ๊ฒฝ๋ก์ ๋ค์ด๊ฐ๋๋ผ๋ ์์ ๊ฒฝ๋ก์ ์ปดํฌ๋ํธ๊ฐ ํญ์ ๋ณด์ด๊ฒ ํ๊ณ ์ถ์ ๋๋ ์ด๋ป๊ฒ ํด์ผํ ๊น?
๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.
Route๋ฅผ ์ค์ฒฉํด์ค๋ค.(Nest Routes)
ํญ์ ๋ณด์ด๊ฒ ํ๊ณ ์ถ์ ์ปดํฌ๋ํธ(์์ ์ปดํฌ๋ํธ)์ Route๋ก ๋๋จธ์ง children์ ๊ฐ์ธ์ฃผ๋ฉด ๋๋ค.
์๋ฅผ ๋ค์ด์, ๋ฐ์ ์์ ์์ ํ์๊ฒฝ๋ก์ ๊ฐ๋๋ผ๋ Home ์ปดํฌ๋ํธ๋ ํญ์ ๋ณด์ด๊ฒ ํ๊ณ ์ถ์ ์ํฉ์ด๋ผ๊ณ ํ์.
import React from "react";
import { Route, Routes } from "react-router-dom";
import Home from "./routes/Home";
import About from "./routes/About";
import Contact from "./routes/Contact";
import NoMatch from "./routes/NoMatch";
const App = () => {
return (
<div>
<Routes>
<Route path="/" element={<Home />} />
<Route path="about/*" element={<About />} />
<Route path="contact" element={<Contact />} />
<Route path="/*" element={<NoMatch />} />
</Routes>
</div>
);
};
export default App;
์ ์์ ๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๊ฒฝํด์ฃผ๋ฉด ๋๋ค.
import React from "react";
import { Route, Routes } from "react-router-dom";
import Home from "./routes/Home";
import About from "./routes/About";
import Contact from "./routes/Contact";
import NoMatch from "./routes/NoMatch";
const App = () => {
return (
<div>
<Routes>
<Route path="/" element={<Home />}>
<Route path="about/*" element={<About />} />
<Route path="contact" element={<Contact />} />
</Route>
<Route path="*" element={<NoMatch />} />
</Routes>
</div>
);
};
export default App;
Home Route๋ก ํ์ ๊ฒฝ๋ก์ ์๋ Route๋ฅผ ๊ฐ์ธ์ฃผ๋ฉด ๋๋ค.
์ฌ๊ธฐ์ ๋์ด ์๋๋ผ ๋ค์์ผ๋ก Home ์ปดํฌ๋ํธ์ Outlet์ด๋ผ๋ ์ปดํฌ๋ํธ๋ฅผ ํ ๋นํด์ค์ผํ๋ค.
Outlet
This means the route will still render its children even without an explicit element prop, so you can nest route paths without nesting UI around the child route elements.
์ ํํ ๊ฒฝ๋ก๊ฐ ์ผ์นํ์ง์์๋ ์ปดํฌ๋ํธ๋ฅผ ์ค์ฒฉํจ์ผ๋ก์จ ์์ ์ปดํฌ๋ํธ๋ฅผ ๋ณด์ฌ์ค ์ ์๊ฒ ํ๋ ์ปดํฌ๋ํธ์ด๋ค.
๋ณด์ฌ์ฃผ๊ณ ์ถ์ ๋ถ๋ชจ ์ปดํฌ๋ํธ์ Outlet์ ํ ๋นํด์ฃผ๋ฉด ๋๋ค.
import React from "react";
import { Outlet, Route, Routes } from "react-router-dom";
import ColorNavLink from "./ColorNavLink";
import About from "./About";
import Contact from "./Contact";
const Home = () => {
return (
<div>
<h1>React Router Test Zone</h1>
{ColorNavLink("/", "Home")}|{ColorNavLink("about", "About")}|
{ColorNavLink("contact", "Contact")}
<h2>Welcome!</h2>
<Outlet />
</div>
);
};
export default Home;
์ด๋ฌํ ๋ฐฉ๋ฒ์ผ๋ก ํ์๊ฒฝ๋ก์ ๋ค์ด๊ฐ๋คํ๋๋ผ๋ Home ์ปดํฌ๋ํธ(์์ ์ปดํฌ๋ํธ)๊ฐ ํญ์ ๋ณด์ด๊ฒ ํ ์ ์๋ค.
๊ธฐ๋ณธ๊ฒฝ๋ก
/about
/contact
์ ๋ฆฌ
Nest Routes ํ๋ ๋ฐฉ๋ฒ
1. ๋ณด์ด๊ฒ ํ๊ณ ์ถ์ ์์ ์ปดํฌ๋ํธ๋ก ํ์ ๊ฒฝ๋ก ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ธ์ค๋ค.
2. ์์์ปดํฌ๋ํธ์ Outlet ์ปดํฌ๋ํธ๋ฅผ ํ ๋นํด์ค๋ค.
๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก๋ ๊ฒฝ๋ก์ "๋ณ"์ ์ด์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
์ด๋ Nest Routes๋ฅผ ํ๋ ๋ฐฉ๋ฒ ์ค ํ๋์ด์ง๋ง ๊ณต์๋ฌธ์์์๋ ์ฒซ๋ฒ์งธ ๋ฐฉ๋ฒ์ ๊ถ์ฅํ๊ณ ์๋ค.
์๋ง ๊ทธ ์ด์ ๋ ๊ฒฝ๋ก์ "๋ณ"์ ์ฐ๋ ๋ฐฉ๋ฒ์ ์๋ ๊ฒฝ๋ก์๋ ๋ถ๋ชจ์ปดํฌ๋ํธ๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ๋๋ฌธ์ด๋ผ๊ณ ์๊ฐํ๋ค.
"๋ณ"์ ์ฐ๋ฉด ๋ถ๋ชจ๊ฒฝ๋ก๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ชจ๋ ํ์ ๊ฒฝ๋ก์ ํด๋น ๋ถ๋ชจ์ปดํฌ๋ํธ๋ฅผ ๋ณด์ฌ์ฃผ๊ฒ ๋๋ค.
๋๋ฌธ์ ์๋ ๊ฒฝ๋ก์ ๋ค์ด๊ฐ๋๋ผ๋ ์ปดํฌ๋ํธ๋ฅผ ๋ณด์ฌ์ค ์ ์๊ธฐ ๋๋ฌธ์ ์ฒซ๋ฒ์งธ ๋ฐฉ๋ฒ์ ๋ ์ ํธํ๋ค๊ณ ์๊ฐํ๋ค.
url์ params๋ ๋ฌด์์ธ๊ฐ?
url์ ๊ฒฝ๋ก๋ฅผ ๋์ ์ผ๋ก ์กฐ์ํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์ด๋ค.
์ ์ ์ผ๋ก ๊ฒฝ๋ก๋ฅผ ์ผ์ผํ ์ง์ ํ์ฌ ๋ผ์ฐํ
ํด์ฃผ๋ ๊ฒ์ด ์๋๋ผ ์ง์ ํ์ง ์์ ๊ฒฝ๋ก์ ๋ค์ด๊ฐ๋ ๋ผ์ฐํ
๋๊ฒ ํด์ค๋ค.
์ ์ฌ์ฉํ๋๊ฐ?
์ด๋ ํ ๊ฒฝ๋ก๋ฅผ ๊ธฐ์ค์ผ๋ก ํ์ฌ ํ์ ๊ฒฝ๋ก๋ง๋ค ๊ฐ๊ฐ ๋ค๋ฅธ ๋ฐ์ดํฐ๋ค์ ๋ณด์ฌ์ฃผ๊ณ ์ถ์ ๋ ์ฌ์ฉํ ์ ์๋ค.
์ด ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ฐ ๋ผ์ฐํ ํด์ฃผ๋ ๊ฒ๋ณด๋ค params๋ฅผ ์ด์ฉํ์ฌ ๋์ ์ผ๋ก ๋ผ์ฐํ ํด์ฃผ๋ ๊ฒ์ด ๊ฐ๋ ์ฑ ๋ฐ ์ ์ง๋ณด์์ ํธ๋ฆฌํจ์ ์ฃผ๊ธฐ ๋๋ฌธ์ด๋ค.
๋ค์ ์์ ๋ฅผ ๋ณด์.
import React, { useEffect, useState } from "react";
import { Route, Routes } from "react-router-dom";
import Home from "./routes/Home";
import About from "./routes/About";
import Contact from "./routes/Contact";
import NoMatch from "./routes/NoMatch";
import User from "./routes/User";
const App = () => {
const users = [
{ position: "user1", userId: 1, name: "mark" },
{ position: "user2", userId: 2, name: "cavin" },
{ position: "user3", userId: 3, name: "merry" },
];
return (
<div>
<Routes>
<Route path="/" element={<Home />}>
<Route path="about" element={<About users={users} />}>
{users.map((user) => {
return (
<Route
key={user.userId}
path={user.position}
element={<User />}
/>
);
})}
</Route>
<Route path="contact" element={<Contact />} />
</Route>
<Route path="*" element={<NoMatch />} />
</Routes>
</div>
);
};
export default App;
์ ์์ ์์๋ Aboutํ์ด์ง์์ array.prototype.map๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ user๋ฅผ ๋ผ์ฐํ ํด์ฃผ๊ณ ์๋ค.
ํ์ง๋ง params๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํํํ ์ ์๋ค.
import React, { useEffect, useState } from "react";
import { Route, Routes } from "react-router-dom";
import Home from "./routes/Home";
import About from "./routes/About";
import Contact from "./routes/Contact";
import NoMatch from "./routes/NoMatch";
import User from "./routes/User";
const App = () => {
const users = [
{ position: "user1", userId: 1, name: "mark" },
{ position: "user2", userId: 2, name: "cavin" },
{ position: "user3", userId: 3, name: "merry" },
];
return (
<div>
<Routes>
<Route path="/" element={<Home />}>
<Route path="about" element={<About users={users} />}>
<Route path=":usernumber" element={<User />} />
</Route>
<Route path="contact" element={<Contact />} />
</Route>
<Route path="*" element={<NoMatch />} />
</Routes>
</div>
);
};
export default App;
data๋ฅผ ๊ธฐ์ค์ผ๋ก ์ฌ๋ฌ Route๋ฅผ ๋งตํํ์ง์๊ณ params๋ก ๋์ ์ผ๋ก ์กฐ์ํ์ฌ ํ์ค์ Route๋ก๋ง ๊ตฌํํ ์ ์๋ค.
์ฌ์ฉ๋ฒ
์์ ์์ ๋ฅผ ์ฐธ๊ณ ํ์ฌ ์ฌ์ฉ๋ฒ์ ์ดํด๋ณด๊ฒ ๋ค.
(
<div>
<Routes>
<Route path="/" element={<Home />}>
<Route path="about" element={<About users={users} />}>
<Route path=":usernumber" element={<User />} />
</Route>
<Route path="contact" element={<Contact />} />
</Route>
<Route path="*" element={<NoMatch />} />
</Routes>
</div>
);
about๊ฒฝ๋ก๋ฅผ ๊ธฐ์ค์ผ๋ก usenumber๋ผ๋ param์ ํ ๋นํด์ฃผ์๋ค.
์ด ๋ about๊ฒฝ๋ก์์ ์ด๋ค ๊ฒฝ๋ก๋ก ์ด๋ํ์ฌ๋ User๋ผ๋ ์ปดํฌ๋ํธ๋ฅผ ๋ณด์ฌ์ฃผ๊ฒ ๋๋ค. (์ด๊ฒ์ด ๋์ ์ผ๋ก url์ ์กฐ์ํ ์ ์๋ค๋ ์๋ฏธ)
์ผ์นํ์ง์์ url์ด ์๋ค๋ฉด ๋น ํ๋ฉด์ด๊ฑฐ๋ NoMatch ํ๋ฉด์ด ๋ํ๋๊ฑฐ๋ ํด์ผํ์ง๋ง params๋ฅผ ์ค์ ํด์ค๋ค๋ฉด ํ ๋นํ ์ปดํฌ๋ํธ๊ฐ ๋ํ๋๋ค.
์ด๋ฅผ ํตํด ์ฌ๋ฌ Route๋ฅผ ์ผ์ผํ ์ค์ ํด์ฃผ์ง ์์๋ ๋๋ค๋ ์ฅ์ ์ ์ง๋๊ฒ ๋๋ค.
url params ์ฌ์ฉํ๊ธฐ
๋ด๊ฐ ๋์ ์ผ๋ก ์
๋ ฅํ url param์ ์ด์ฉํ๊ณ ์ถ๋ค๋ฉด useParams๋ผ๋ ํ
์ ์ฌ์ฉํ๋ฉด ๋๋ค.
import { useParams } from "react-router-dom";
const params = useParams
console.log(params)
useParams ํ ์ ๋ถ๋ฌ์ค๋ฉด ๋ด๊ฐ ์ฌ์ฉํ๊ณ ์๋ params๋ฅผ ๋ชจ์๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํด์ค๋ค.
์๊น ์์์ ์ง์ ํด์ค usernumber๋ผ๋ params์ ๋ค์ด๊ฐ ๊ฒฝ๋ก์ ๋ํ ์ ๋ณด๋ฅผ ๊ฐ์ฒด๋ก ๋ณด์ฌ์ฃผ๊ณ ์๋ค.
url params๋ ํญ์ ๋ฌธ์์ด์ด๊ธฐ ๋๋ฌธ์ ๊ฐ์ ธ์์ผํ params๊ฐ ์ซ์๋ผ๋ฉด ๊ฐ์ ธ์ฌ ๋ ์ซ์ํ์์ผ์ ๊ฐ์ ธ์์ผํ๋ค. ex) parseInt()
์ ์ํ ๊ฒฝ๋ก์ ์ด๋ฆ์ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์๊ฒ ๋ค.
import React from "react";
import { useParams } from "react-router-dom";
const User = () => {
const params = useParams();
console.log(params);
return (
<div>
<h1>User Number : {params.usernumber}</h1>
</div>
);
};
export default User;
์์ ๊ฐ์ด ์ค์ ํด์ค๋ค๋ฉด param ๊ฒฝ๋ก์ ๋ํ ์ ๋ณด๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
user1๊ฒฝ๋ก์ ์ ์ํ๋ user1์ด๋ผ๋ ๊ฒฝ๋ก๋ฅผ ํ๋ฉด์ ๋ํ๋ด๊ณ user2 ๊ฒฝ๋ก์ ์ ์ํ๋ user2๋ผ๋ ๊ฒฝ๋ก๋ฅผ ํ๋ฉด์ ๋ํ๋ธ๋ค.
์ด๋ ๊ฒ ๋์ ์ผ๋ก ๋ง์ ์์ด Route๋ฅผ ์ง์ ํ๊ณ ์ถ์ ๋์๋ route params๋ฅผ ํ์ฉํ๋ฉด ์ข๋ค๊ณ ์๊ฐ๋๋ค.
์ ๋ฆฌ
params๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
1. Route path prop์ ":paramname"์ ํ ๋นํ๋ค.
<Route path =":paramname" element ={<Component/>}/>
2. paraname์ ํ์ฉํ๊ณ ์ถ๋ค๋ฉด useParamsํ ์ ์ฌ์ฉํ์ฌ ์ฌ์ฉํ๋ค.
const params = useParams()
Route์ปดํฌ๋ํธ์ prop๊ฐ์ผ๋ก index๋ผ๋ ๊ฐ์ ๋ฃ์ด์ฃผ๋ ๊ฒ์ด๋ค.
index์ ์ญํ ์ ๋ถ๋ชจ ๊ฒฝ๋ก์ ๋ค์ด๊ฐ์ ๋ ๋ณด์ฌ์ค element์ ์ง์ ํ๋๊ฒ์ด๋ค.
์ฌ๋ฌ๊ฐ์ง ํ์๊ฒฝ๋ก๋ฅผ ๊ฐ์ง๊ณ ์๋ ๋ถ๋ชจ๊ฒฝ๋ก๊ฐ ์๋ค๊ณ ํ์.
์ด ๋ ๋ถ๋ชจ๊ฒฝ๋ก์ ๋ค์ด๊ฐ์ ๋ ๋ณด์ฌ์ง๋ element๊ฐ ์์ด์ผํ๋ค.
์๋ฅผ ๋ค์ด, ํ์ ๊ฒฝ๋ก๋ก ๋ค์ด๊ฐ์ ๋ item๋ค์ ๋ณด์ฌ์ค๋ค๊ณ ํ์์ ๋ ๋ถ๋ชจ๊ฒฝ๋ก์ ๋ค์ด๊ฐ์ ๋ Select the Item!์ด๋ผ๋ element๋ฅผ ๋ณด์ฌ์ฃผ๊ณ ์ถ๋ค๊ณ ํ์.
์ด ๋ ํด๋น element๋ ์์ ๊ฒฝ๋ก๋ก ๋ค์ด๊ฐ์ ๋ ๋ณด์ฌ์ผํ๊ณ ํ์๊ฒฝ๋ก๋ก ๋ค์ด๊ฐ์ ๋์๋ ์๋ณด์ฌ์ผํ๋ค.
์ด๋ด ๋ index prop์ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
๋ถ๋ชจ Route๋ก ํ์ Route๋ฅผ Nestํ์ ๊ฒฝ์ฐ ํ์ Route ์ค ํ๋์ path๋ฅผ ์
๋ ฅํด์ค ํ์์์ด index prop๋ง ํ ๋นํด์ฃผ๊ณ element๋ฅผ ํ ๋นํด์ค๋ค.
์์
<Route path ="/invoices" element = {<Invoices/>}>
<Route index element = {<h1>Select the Invoice!</h1>}
<Route path =":invoiceId" element = {<Invoice/>}/>
</Route>
์ ์์์์ invoices๋ผ๋ ๊ฒฝ๋ก์ ๋ค์ด๊ฐ์ ๋ Invoices์ปดํฌ๋ํธ๊ฐ Outlet๋๋ฉฐ ๋ณด์ฌ์ง ๊ฒ์ด๋ฉฐ ํ์ ๊ฒฝ๋ก๋ก ๋ค์ด๊ฐ๋คํ์ฌ Invoices ์ปดํฌ๋ํธ๋ด์ฉ์ ๋ณด์ฌ์ง ๊ฒ์ด๋ค.
ํ์ง๋ง ๋ถ๋ชจ๊ฒฝ๋ก์์๋ ๋ณด์ฌ์ง๊ณ ํ์ ๊ฒฝ๋ก๋ก ๋ค์ด๊ฐ์ ๋ ์ฌ๋ผ์ง element๊ฐ ํ์ํ ๋ ์์ ๊ฐ์ด index prop์ ํ์ฉํด์ฃผ๋ฉด ๋๋ ๊ฒ์ด๋ค.
๊ทธ๋ ๋ค๋ฉด ์ฒ์ invoices๋ผ๋ ์์ ๊ฒฝ๋ก์ ๋ค์ด๊ฐ์ ๋ Select the voice๋ผ๋ ๋ฌธ๊ตฌ๊ฐ ๋ณด์ฌ์ง๊ณ ํ์ ๊ฒฝ๋ก๋ก ์ด๋ํ์์ ๋์๋ ํด๋น ๋ฌธ๊ตฌ๊ฐ ๋ณด์ด์ง ์๊ฒ ๋ ๊ฒ์ด๋ค.
index prop์ ํ์ฉํ์ง ์๋๋ผ๋ ๋ฐ๋ก invoices Route์์ invoices Route๋ฅผ ๋ง๋ค์ด์ฃผ๋ ๋ฐฉ๋ฒ๋ ์๊ฒ ์ง๋ง ์ด๋ ๊ฐ๋ ์ฑ์ ํด์น ์ ์์ผ๋ฉฐ ์ข์ ๋ฐฉ๋ฒ์ ์๋๋ค.
๋ฐ๋ผ์, ์ํฉ์ ๋ฐ๋ผ element๋ฅผ ๋ณด์ฌ์ง๊ฒ ํ๊ฑฐ๋ ์ฌ๋ผ์ง๊ฒ ํ๊ธฐ ์ํด์ index prop์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ ์ํ ์ ์๊ฒ ๋ค.
const [searchParams,setSearchParams] = useSearchParams()
useSearchParams๋ ํ์ฌ location์ ๋ํ์ฌ url์ query string์ ์ฝ๊ณ ๋ณ๊ฒฝํ๋๋ฐ ์ฌ์ฉ๋๋ค.
useSearchParams๋ useState hook์ฒ๋ผ ๋๊ฐ์ ๊ฐ์ ๋ด์ ๋ฐฐ์ด์ ๋ฐํํ๋ค.
searchParams : ํ์ฌ location์ search params
setSearchParams : searchParams๋ฅผ ์ ๋ฐ์ดํธ ํด์ฃผ๋ ํจ์
์ฐธ์กฐ :