[React] ๋ฆฌ์กํธ ๋ผ์ฐํฐ React Router v6 ๋ฐ๋์ ํบ์๋ณด๊ธฐ
React Router๊ฐ v6์ผ๋ก ์
๋ฐ์ดํธ ๋๋ฉด์ ๊ฝค ๋ง์ ๋ถ๋ถ์ด ๋ฐ๋์๋ค. ๊ณต์ ๋ฌธ์์์ ์์ธํ ๋ง์ด๊ทธ๋ ์ด์
๊ฐ์ด๋๋ ์ ๊ณตํ๊ณ ์๋ค. v6์ ์ฌ์ฉํ๋ ค๋ฉด React 16.8
๋ฒ์ ์ด์ ์ฌ์ฉํด์ผ ํ๋ค. v6์ ์ด์ ๋ฒ์ ๋๋น ๋ฒ๋ค ์ฌ์ด์ฆ๋ 70%
์ด์ ์ค์๋ค๊ณ ํ๋ค(ํจํค์ง ์
๋ฐ์ดํธ๋ง์ผ๋ก ๋ฒ๋ค ํฌ๊ธฐ ์ต์ ํ๊ฐ ๊ฐ๋ฅํ๋ค๋ ๋ป).
Switch → Routes
<Switch>
์ปดํฌ๋ํธ๊ฐ <Routes>
๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ณ๊ฒฝ๋๋ค. ๋ฐ๋ ์ด๋ฆ์ด ๋ ์ง๊ด์ ์ธ ๊ฒ ๊ฐ๋ค. <Route>
๋ง ๋จ๋
์ผ๋ก ์ฌ์ฉํ ์๋ ์๊ฒ ๋๋ค. <Route>
๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ํญ์ <Routes>
๋ก ๊ฐ์ธ์ค์ผ ํ๋ค.
// v5
<Switch>
<Route ... />
</Switch>
// v6
<Routes>
<Route ... />
</Route>
exact ์ต์ ์ญ์
v6๋ถํฐ ๊ฒฝ๋ก๊ฐ ์ ํํ ์ผ์นํ๋๋ก ๋งค์นญ ๊ท์น์ด ๋ฐ๊ผ๋ค. ๋์ด์ exact
์ต์
์ ๋ช
์ํ์ง ์์๋ ๋๋ค. ๋ชจ๋ ๋ผ์ฐํธ๋ ๊ธฐ๋ณธ์ ์ผ๋ก exact
์ต์
์ด ๋ถ๋๋ค๊ณ ๋ณด๋ฉด ๋๋ค. ํ์ ๊ฒฝ๋ก์ ๋ค๋ฅธ ๋ผ์ฐํธ๋ฅผ ๋งค์นญ์ํค๊ณ ์ถ์ ๋(์๋ธ ๊ฒฝ๋ก๊ฐ ํ์ํ ๋) URL ๋ค์ *
๊ธฐํธ๋ฅผ ๋ถ์ด๋ฉด ๋๋ค.
// v5 (exact ์ต์
์ ๋ถ์ด๊ธฐ ์์๊ธฐ ๋๋ฌธ์ /profiles/... ํ์ ๊ฒฝ๋ก๊ฐ ๋งค์นญ๋ ์ ์๋ค)
<Route path="/profiles" />
// v6
<Route path="/profiles/*" />
element ์์ฑ
v5์์ Route ์ปดํฌ๋ํธ๋ฅผ ๋ ๋ํ ๋ component
render
children
์์ฑ์ ์ฌ์ฉํ๋ค. v6 ๋ถํด ์ด ์์ฑ๋ค์ด ๋ชจ๋ ์์ด์ง๊ณ element
๋ก ํต์ผ๋๋ค. ๋์ด์ inline function์ ์ด์ฉํด routeProps
๋ฅผ ๋๊ธธ ์๋ ์๋ค. ๋์ Router์์ ์ ๊ณตํ๋ Hooks(useLocation
๋ฑ)๋ฅผ ํตํด ๋ผ์ฐํธ ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์๋ค.
// v5
<Route path="profiles" component={Profiles} />
<Route path="profiles" render={(routeProps) => <Profiles {...routeProps} />} />
// v6
<Route path="/profiles/*" element={<Profiles />} />
<Route> index ์์ฑ
Route
์์ index
๋ผ๋ props๋ฅผ ์ฌ์ฉํ ์ ์๋ค. index
๋ path=’/’
์ ๋์ผํ ์๋ฏธ๋ฅผ ๊ฐ์ง๋ค. ์ฆ, ํด๋น ๋ผ์ฐํธ๋ด์์ ๊ฐ์ฅ ์์ ๊ฒฝ๋ก๋ฅผ ๊ฐ๋ฆฌํจ๋ค๊ณ ๋ณด๋ฉด ๋๋ค. ์๋ฅผ๋ค๋ฉด...
‘/’
๊ฒฝ๋ก์ ์๋ธ ๋ผ์ฐํธindex
๋‘/’
‘/courses’
๊ฒฝ๋ก์ ์๋ธ ๋ผ์ฐํธindex
๋‘/courses’
- ...
์๋ ์์์์ /courses
๊ฒฝ๋ก์ ์ง์
ํ๋ฉด ์ฒซ๋ฒ์งธ ์๋ธ ๋ผ์ฐํธ์ index
๋ /courses
๊ฒฝ๋ก์ ๋์ผํ๋ฏ๋ก CoursesIndex
์ปดํฌ๋ํธ๋ฅผ ๋ ๋ํ๋ค.
๊ณต์ ๋ฌธ์ ์์ โผ
function Courses() {
return (
<div>
<h2>Courses</h2>
<Outlet /> {/* ๊ฒฝ๋ก์ ๋ฐ๋ผ CoursesIndex ํน์ Course ์ปดํฌ๋ํธ ๋ ๋ */}
</div>
);
}
// CoursesIndex / Course ์ปดํฌ๋ํธ ์๋ต
const App = () => {
return (
<Routes>
<Route path="/courses" element={<Courses />}>
<Route index={true} element={<CoursesIndex />} />
<Route path="/courses/:id" element={<Course />} />
</Route>
</Routes>
);
};
export default App;
useRouteMatch → ์๋๊ฒฝ๋ก
v6๋ถํฐ ์๋๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ ์ ์๋ค. .
์ ํ์ฌ ๊ฒฝ๋ก(๋ผ์ฐํธ) ..
์์ ๊ฒฝ๋ก๋ฅผ ๊ฐ๋ฆฌํจ๋ค. ์จ์ .
์ด ์๋ ์ฌ๋์ /
๋ฅผ ์ด์ฉํด์ ์
๋ ฅํ๋ฉด(/profiles
) ์ ๋๊ฒฝ๋ก๋ก ํด์ํ๋ ์ ์ฃผ์
// v5 (์ ๋๊ฒฝ๋ก๋ง ๊ฐ๋ฅ)
<Link to="/profiles/smith">smith</Link>
// v6 (์๋๊ฒฝ๋ก ๋ฐ ์ ๋๊ฒฝ๋ก ๋ชจ๋ ๊ฐ๋ฅ)
// ํ์ฌ ๊ฒฝ๋ก๊ฐ /profiles๋ผ๊ณ ๊ฐ์
<Link to="smith">smith</Link> // "/profiles/smith"
<Link to="./smith">smith</Link> // "/profiles/smith"
<Link to=".">smith</Link> // "/profiles"
<Link to="..">smith</Link> // "/"
<Link to="../smith">smith</Link> // "/smith"
match
๊ฐ์ฒด์ ์ ๊ทผํ ์ ์๋ useRouteMatch
Hook๋ v6์์ ์ฌ๋ผ์ก๋ค. ๋์ ์๋๊ฒฝ๋ก๋ฅผ ์ฐ๋ฉด ๋๋ค.
// ํ์ฌ ๊ฒฝ๋ก๊ฐ /home ์ด๋ผ๊ณ ๊ฐ์
// v5
const match = useRouteMatch(); // {path: '/home', url: '/home', isExact: true, params: {…}}
<Link to={match.url} /> // ํ์ฌ url('/home')๋ก ์ด๋ํ๋ ๋งํฌ
<Route exact path={`${match.path}/about`} /> // '/home/about'์ ๋ํ ๋ผ์ฐํธ
// v6
<Link to="."/> // '/home'
<Route path="about"/> // '/home/about'
ํน์ useRouteMatch
์ ์ ์ฌํ useMatch
๋ฅผ ์ฌ์ฉํ ์๋ ์๋ค. ํ์ฌ ๊ฒฝ๋ก์ useMatch
ํ๋ผ๋ฏธํฐ๋ก ๋๊ธด ๊ฒฝ๋ก๊ฐ ์ผ์นํ๋ค๋ฉด ๊ด๋ จ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ๊ณ , ์ผ์นํ์ง ์๋๋ค๋ฉด null
์ ๋ฐํํ๋ค.
// ํ์ฌ ๊ฒฝ๋ก๊ฐ "/profiles" ๋ผ๊ณ ๊ฐ์
const match = useMatch('/profiles')
console.log(match) // {params: {…}, pathname: '/profiles', pathnameBase: '/profiles', pattern: {…}}
์ค์ฒฉ ๋ผ์ฐํธ (์๋ธ ๋ผ์ฐํธ)
import React from 'react';
import { Route, Link, Routes } from 'react-router-dom';
import About from './components/About';
import Home from './components/Home';
import Profiles from './components/Profiles';
import Profile from './components/Profile';
import './App.css';
const App = function () {
return (
<div className="container">
<h2>๋งํฌ ๋ชฉ๋ก</h2>
<ul>
<li>
<Link to="/">ํ์ผ๋ก ์ด๋</Link>
</li>
<li>
<Link to="/about">์๊ฐ๋ก ์ด๋</Link>
</li>
<li>
<Link to="/profiles">ํ๋กํ ๋ชฉ๋ก</Link>
</li>
</ul>
<hr />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
{/* ๋ฐฉ๋ฒ 1 : ๋ถ๋ชจ ๋ผ์ฐํธ ๊ฒฝ๋ก์ "/profiles/*" ์
๋ ฅ์(ํ์ Route ์์์ ์ฃผ์) */}
<Route path="/profiles/*" element={<Profiles />}>
<Route path=":username" element={<Profile />} />
<Route path="*" element={<div>์ ์ ๋ฅผ ์ ํํด์ฃผ์ธ์ </div>} />
</Route>
{/* ๋ฐฉ๋ฒ 2 : ๋ถ๋ชจ ๋ผ์ฐํธ ๊ฒฝ๋ก์ "/profiles" ์
๋ ฅ์(์ถ์ฒ) */}
<Route path="/profiles" element={<Profiles />}>
<Route index={true} element={<div>์ ์ ๋ฅผ ์ ํํด์ฃผ์ธ์ </div>} />
<Route path=":username" element={<Profile />} />
</Route>
</Routes>
</div>
);
};
export default App;
์๋ธ ๋ผ์ฐํธ(์ค์ฒฉ ๋ผ์ฐํธ)๋ ์๋์ฒ๋ผ ๋ผ์ฐํธ(/profiles
) ๋ด๋ถ์ ๋ผ์ฐํธ(/profiles/:username
)๋ฅผ ๋ ๋ง๋๋ ๊ฒ์ ์๋ฏธํ๋ค.
/profiles
๊ฒฝ๋ก ๋ผ์ฐํธ :<div>์ ์ ๋ฅผ ์ ํํด์ฃผ์ธ์</div>
์๋ฆฌ๋จผํธ ๋ ๋- (
/profiles
๊ฒฝ๋ก์์)์ ์ ์ ํ ํ/profiles/:username
๊ฒฝ๋ก๋ก ๋ผ์ฐํธ- ๊ธฐ์กด
<div>...</div>
์๋ฆฌ๋จผํธ๋ ๋ง์ดํธ ํด์ ๋๊ณ <Profile>
์ปดํฌ๋ํธ ๋ ๋
- ๊ธฐ์กด
React Router v5์์ exact
์์ฑ์ ํ์ฉํด ์๋ธ ๋ผ์ฐํธ๋ฅผ ๊ตฌํํ๋ค. ์๋๋ v5 ์ฝ๋ โผ
// App.js
<Route path="/profiles" component={Profiles} />
// Profiles.js
<Route path="/profiles" exact render={() => <div>์ ์ ๋ฅผ ์ ํํด์ฃผ์ธ์ </div>} />
<Route path="/profiles/:username" component={Profile} />
๋ฐฉ๋ฒ 1
v6์์ exact
์์ฑ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ์ ์ฉ๋์ด ์์ผ๋ฏ๋ก *
๋ฅผ ์ด์ฉํด ์๋ธ ๋ผ์ฐํธ๋ฅผ ๊ตฌํํ ์ ์๋ค. v6๋ถํฐ ์๋๊ฒฝ๋ก๋ฅผ ์ง์ํ๋ฏ๋ก /profiles/:username
์ฝ๋๋ :username
๋ง ์
๋ ฅํ๋ฉด ๋๋ค.
v6 ์ฝ๋ - ๋ฐฉ๋ฒ 1 โผ
// App.js
<Routes>
<Route path="/profiles/*" element={<Profiles />} />
</Routes>
// Profiles.js
// ํ์ฌ ๊ฒฝ๋ก(/profiles)์์ ๋งค์นญํ๋ ์๋ธ ๊ฒฝ๋ก๊ฐ ์์๋๋ฅผ ๋งค์นญํ๊ณ ์ถ์ ๋,
// path="*" ํน์ path="" ํํ๋ก ์
๋ ฅํ๋ฉด ๋๋ค.
<Routes>
<Route path="*" element={<div>์ ์ ๋ฅผ ์ ํํด์ฃผ์ธ์ </div>} /> {/* "/profiles" */}
<Route path=":username" element={<Profile />} /> {/* "/profiles/:username" */}
</Routes>
๋ฐฉ๋ฒ 2-1 — Outlet ํ์ฉ
๐ก Outlet์ ์ค์ฒฉ ๋ผ์ฐํธ, ๊ณตํต์ ์ผ๋ก ๋ณด์ฌ์ผํ ๋ ์ด์์์ด ์์ ๋๋ ์ ์ฉํ๋ค
React Router v6์ ์๋กญ๊ฒ ์ถ๊ฐ๋ <Outlet>
์ ์ฌ์ฉํ ์๋ ์๋ค. 1๊ฐ ํ์ผ(์์์์ App.js
)์ ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ๊ณ , ์ค์ฒฉ ๋ผ์ฐํธ(์๋ธ ๋ผ์ฐํธ) ๋๋ ๊ณณ์ <Outlet />
์ฝ๋๋ง ์ถ๊ฐํ๋ฉด ๋๋ค. ํ ๊ณณ์์ ์ค์ฒฉ ๋ผ์ฐํธ๋ฅผ ๊ด๋ฆฌํ ์ ์์ด ๋ ํธํ๋ค. (ํ์ Route
์์ ์ฃผ์. :username
๊ฒฝ๋ก์ ๋ํ ๋ผ์ฐํธ๊ฐ ์์ ์์ผํจ)
v6 ์ฝ๋ - ๋ฐฉ๋ฒ 2 (Outlet ํ์ฉ) โผ
// App.js
import { Routes, Route, Outlet } from 'react-router-dom';
<Routes>
<Route path="/profiles/*" element={<Profiles />}>
<Route path=":username" element={<Profile />} />{' '}
{/* "/profiles/:username" */}
<Route path="*" element={<div>์ ์ ๋ฅผ ์ ํํด์ฃผ์ธ์</div>} />{' '}
{/* "/profiles/*" */}
</Route>
</Routes>;
// Profiles.js
<Outlet />
/*
์๋ 2๊ฐ์ค 1๊ฐ๊ฐ ๋ผ์ฐํธ๋จ
"/profiles" ํน์ "/profiles/*" ๊ฒฝ๋ก → <div>์ ์ ๋ฅผ ์ ํํด์ฃผ์ธ์</div>
"/profiles/:username" ๊ฒฝ๋ก → <Profile>
*/
๋ฐฉ๋ฒ 2-2 — Outlet + Route Index ํ์ฉ (์ถ์ฒ)
Outlet
์ ํ์ฉํด ์๋ธ ๋ผ์ฐํธ๋ฅผ ๊ตฌํํ๋ ์ํฉ์์, /profiles/:username
์๋ ๋์ด์ ํ์ ๊ฒฝ๋ก๊ฐ ์๋ค๋ฉด ๋ถ๋ชจ ๋ผ์ฐํธ ๊ฒฝ๋ก์ ๊ตณ์ด *
(asterisk)๋ฅผ ๋ถ์ธ /profiles/*
ํํ๋ก ์์ฑํ์ง ์์๋ ๋๋ค.
๋ถ๋ชจ ๋ผ์ฐํธ์ *
๊ธฐํธ ์์ด /profiles
๊ฒฝ๋ก๋ง ์
๋ ฅํ๊ณ , ์์ ๋ผ์ฐํธ(/profiles
)์ ์ผ์นํ์ง๋ง ๊ทธ ์ดํ ๊ฒฝ๋ก๊ฐ ์ฃผ์ด์ง์ง ์์ ์ํฉ์ ๋งค์นญ๋ ์๋ธ ๋ผ์ฐํธ์ index
props๋ฅผ ๋๊ธฐ๋ ๋ฐฉ์์ผ๋ก ์์ฑํ ์๋ ์๋ค.
`Route`์ `index` ์์ฑ์ ํด๋น ๋ผ์ฐํธ์ ๊ฐ์ฅ ์์ ๊ฒฝ๋ก๋ฅผ ๊ฐ๋ฆฌํจ๋ค. ์ด ์์ ์์ `/profiles` ๊ฒฝ๋ก์ ๊ฐ๋ค.
// App.js
<Routes>
<Route path="/profiles" element={<Profiles />}>
<Route index element={<div>์ ์ ๋ฅผ ์ ํํด์ฃผ์ธ์</div>} /> {/* "/profiles" */}
<Route path=":username" element={<Profile />} />{' '}
{/* "/profiles/:username" */}
</Route>
</Routes>;
/profiles
๊ฒฝ๋ก ๋ ๋ ์ปดํฌ๋ํธ : ๋ฐฉ๋ฒ 2-1 / ๋ฐฉ๋ฒ 2-2 ๋ชจ๋<div>์ ์ ๋ฅผ ์ ํํด์ฃผ์ธ์ </div>
/profiles/:username
๊ฒฝ๋ก ๋ ๋ ์ปดํฌ๋ํธ : ๋ฐฉ๋ฒ 2-1 / ๋ฐฉ๋ฒ 2-2 ๋ชจ๋<Profile />
/profiles/:username/123
๊ฒฝ๋ก ๋ ๋ ์ปดํฌ๋ํธ- ๋ฐฉ๋ฒ 2-1 :
<div>์ ์ ๋ฅผ ์ ํํด์ฃผ์ธ์ </div>
- ๋ฐฉ๋ฒ 2-2 : ๋งค์นญํ๋ ๋ผ์ฐํธ๊ฐ ์์ผ๋ฏ๋ก ์๋ฌด๊ฒ๋ ๋ ๋ํ์ง ์์. ์ด๋
path=”:username”
์ ๋ํ ํ์ ๋ผ์ฐํธ(/profiles/:username/123
)๋ฅผ ์ง์ ํด์ฃผ๋ฉด ๋๋ค.
- ๋ฐฉ๋ฒ 2-1 :
useHistory → useNavigate
v6๋ถํฐ useHistory
์ด๋ฆ์ด useNavigate
๋ก ๋ณ๊ฒฝ๋๋ค. v5์ useHistory
๋ฅผ ์คํํ๋ฉด ๊ฐ์ฒด๋ฅผ ๋ฐํํ๊ณ , ์ด ๊ฐ์ฒด์ push
replace
๊ฐ์ ๋ฉ์๋๊ฐ ํฌํจ๋ผ์๋ค. ๋ฐ๋ฉด v6์ useNavigate
๋ฅผ ์คํํ๋ฉด ํจ์ ์์ฒด๋ฅผ ๋ฐํํ๋ค. ๋๋ฌธ์ navigate
๋ ํจ์ ํธ์ถ์ฒ๋ผ ์จ์ผํ๋ค. navigate
์๋ ์๋๊ฒฝ๋ก๋ฅผ ์ธ ์ ์๋ค.
// ํ์ฌ ๊ฒฝ๋ก๊ฐ 'profiles'๋ผ๊ณ ๊ฐ์
// v5
const history = useHistory();
history.push('/profiles/smith');
history.replace('/profiles/smith');
history.go(1); // 1ํ์ด์ง forward
history.go(-2); // 2ํ์ด์ง back
// v6
const navigate = useNavigate();
navigate('smith'); // (์๋๊ฒฝ๋ก)"profiles/smith"
navigate('/profiles/smith', { replace: true }); // ์ ๋๊ฒฝ๋ก
navigate(1);
navigate(-2);
push, replace ์ฐจ์ด์ ๋น๊ต
๐ก React Router์ ๋ฅผ ํตํด ์ด๋ํ ๋๋ง๋ค history stack ์์ธ๋ค. replace๋ ๋ก๊ทธ์ธ์ ๋ง์น๊ณ ์ด๋ํ ๋ค์ ํ์ด์ง์์ ๋ค๋ก๊ฐ๊ธฐ ๋ฒํผ์ ๋๋ ์ ๋ ๋ค์ ๋ก๊ทธ์ธ ํ๋ฉด์ด ๋ณด์ด์ง ์๋๋กํ ๋ ์ ์ฉํ๋ค.
replace๋ฅผ ์ฌ์ฉํ๋ฉด history stack์ ์์ฌ ์๋ ๊ฐ์ฅ ๋ง์ง๋ง ์์('/profiles'
)๋ฅผ ์ด๋ํ ๊ฒฝ๋ก('/profiles/smith'
)๋ก ๋์ฒดํ๋ค. ์ด๋ ํ ์ด์ ๊ฒฝ๋ก๋ฅผ ๋จ๊ธฐ์ง ์์ ๋ replace
๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
push
์ด์ฉ์- ์ด๋ :
'/'
→'/profiles'
→'/profiles/smith'
- ๋ง์ง๋ง ํ์ด์ง์์ ๋ค๋ก๊ฐ๊ธฐ ํ :
'profiles'
- history stack:
['/', 'profiles', 'profiles/smith']
- ์ด๋ :
replace
์ด์ฉ์- ์ด๋ :
'/'
(push) →'/profiles'
(replace) →'/profiles/smith'
- ๋ง์ง๋ง ํ์ด์ง์์ ๋ค๋ก๊ฐ๊ธฐ ํ :
'/'
- history stack:
['/', 'profiles/smith']
- ์ด๋ :
state ๋๊ธฐ๊ธฐ
navigate
๋๋ฒ์งธ ํ๋ผ๋ฏธํฐ(๊ฐ์ฒด)๋ฅผ ํตํด ์ํ๋ state
๋ฅผ ๋๊ธธ ์๋ ์๋ค.
// Profiles.js
// v5
history.push({ pathname: '/profiles/smith', state: { name: 'smith' } });
// v6
navigate('smith', { state: { name: 'smith' } });
// Profile.js
import { useLocation } from 'react-router-dom';
const Profile = function () {
const { state } = useLocation();
console.log(state); // {name: 'smith'}
};
Redirect → Navigate
๐ก Navigate๋ useNavigate ํจ์์ ์ปดํฌ๋ํธ ๋ฒ์
v6๋ถํฐ <Redirect>
์ปดํฌ๋ํธ๊ฐ ์์ด์ง๊ณ <Navigate>
๋ก ๋์ฒด๋๋ค. ๊ธฐ์กด <Redirect>
๋ replace
๋ก์ง์ผ๋ก ์๋ํ์ง๋ง, <Navigate>
๋ push
๋ก์ง์ผ๋ก ์๋ํ๋ค. <Navigate>
์ replace
๋ก์ง์ ์ ์ฉํ๋ ค๋ฉด ์๋์ฒ๋ผ replace={true}
props๋ฅผ ๋๊ธฐ๋ฉด ๋๋ค.
// v5
<Redirect to="about " /> // replace ๋ก์ง์ผ๋ก ์๋
<Redirect to="home" push /> // push ๋ก์ง์ผ๋ก ์๋
// v6
<Navigate to="about" repalce /> // replace ๋ก์ง์ผ๋ก ์๋
<Navigate to="home" /> // push ๋ก์ง์ผ๋ก ์๋
Navigate
๋ useNavigate
๋ฅผ ์ปดํฌ๋ํธ ํํ๋ก ๊ฐ์ผ ๋ฒ์ ์ด๋ค. ๋ฐ๋ผ์ ์ด ๋ ๋ชจ๋ to
replace
state
props๋ฅผ ๋ฐ์ ์ ์๋ค. return()
๋ฌธ ์์์ ์ปดํฌ๋ํธ๋ก ์์ฑํ ๋ Navigate
๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค. ์๋๊ฐ์ ์ํฉ์์ ๋ ์ค ์๋ฌด๊ฑฐ๋ ์จ๋ ๋ฌด๋ฐฉํ๋ค.
import { Navigate, useParams } from 'react-router-dom';
const Profile = function () {
const { username } = useParams();
const profile = profileData[username];
if (!profile) {
return <Navigate to="profiles" />;
// useNavigate()('/profiles')
}
};
useRoutes
๋ฅผ ์ด์ฉํด ๊ฐ์ฒด ํํ๋ก ๋ผ์ฐํธ๋ฅผ ๊ตฌ์ฑํ ๋๋ Navigate
๊ฐ ์ ์ฉํ๊ฒ ์ฐ์ธ๋ค. ์๋์ฒ๋ผ ์กฐ๊ฑด์ ๋ฐ๋ผ ๋ฆฌ๋๋ ์
์ํฌ ๋ Navigate
์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
์ฝ๋ ์ฐธ๊ณ StackOverFlow โผ
// routes.js
import { Navigate } from 'react-router-dom';
const routes = (isLoggedIn) => [
{
path: '/app',
element: isLoggedIn ? <DashboardLayout /> : <Navigate to="/login" />,
children: [
{ path: '/dashboard', element: <Dashboard /> },
{ path: '/account', element: <Account /> },
{ path: '/', element: <Navigate to="/app/dashboard" /> },
// ...
],
},
];
export default routes;
// App.js
import routes from './routes';
import { useRoutes } from 'react-router-dom';
function App() {
const { isLoggedIn } = useSelector((state) => state.auth);
const routing = useRoutes(routes(isLoggedIn));
return <>{routing}</>;
}
Optional URL
ํ๋ผ๋ฏธํฐ๋ฅผ ์ ํ์ ์ผ๋ก ๋ฐ๋ ์ํฉ์์ ?
๋ฌผ์ํ๋ฅผ ํ์ฉํ Optional URL๋ ์์ด์ก๋ค. ํ๋ผ๋ฏธํฐ๊ฐ ์๊ฑฐ๋ ํน์ ์์ ๋ ๋ชจ๋ ํน์ ์ปดํฌ๋ํธ๋ฅผ ๋ ๋ ํ ๋ ์ฌ์ฉํ๋ค. v6์์ ํ์ํ ๋งํผ Route
๋ฅผ ์ ์ํด์ฃผ๋ฉด ๋๋ค.
์๋ ์ฝ๋์์ username
ํ๋ผ๋ฏธํฐ๊ฐ ์์ ๋(/profiles
) ํน์ ์์ ๋(/profiles/smith
) ๋ชจ๋ Profiles
์ปดํฌ๋ํธ๋ฅผ ๋ ๋ํ๋ค.
// v5
<Route path="/profiles/:username?" component={Profiles} />
// v6
<Route path="/profiles/:username" element={<Profiles />} />
<Route path="/profiles/" element={<Profiles />} />
NavLink
NavLink
๋ Link
์ ๋์ผํ๊ฒ ์๋ํ์ง๋ง ํ์ฑํ(to="..."
์ ๋ช
์ํ ๊ฒฝ๋ก์ ํ์ฌ ๊ฒฝ๋ก๊ฐ ์ผ์นํ ๋) ์ฌ๋ถ์ ๋ฐ๋ผ ํน์ ์คํ์ผ์ด๋ ํด๋์ค ์ด๋ฆ์ ์ง์ ํ ์ ์๋ค. v5 ๋๋น ๋ณ๊ฒฝ์ฌํญ์ ์๋์ ๊ฐ๋ค.
<NavLink exact>
→<NavLink end>
์ด๋ฆ ๋ณ๊ฒฝactiveClassName
activeStyle
props ์ ๊ฑฐ. ๋์style
๊ณผclassName
์ ์ธ๋ผ์ธ ํจ์ ์ ๋ฌ ๊ฐ๋ฅ
active ๊ฐ์ฒด
style
๊ณผ className
์์ฑ ์ธ๋ผ์ธ ํจ์์ ์ฒซ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์ ํ์ฑํ ์ฌ๋ถ๋ฅผ ๋ํ๋ด๋ ๊ฐ์ฒด๊ฐ ์ ๋ฌ๋๋ค. ํ์ฌ ๊ฒฝ๋ก๊ฐ to์ ๋ช
์ํ ๊ฒฝ๋ก์ ์ผ์นํ๋ฉด {isActive: true}
, ์ผ์นํ์ง ์์ผ๋ฉด {isActive: false}
๋ก ๋์จ๋ค
<NavLink to="smith" style={(active) => console.log(active)}>
๋งํฌ
</NavLink>;
// console.log -> ๊ฒฝ๋ก๊ฐ ์ผ์นํ๋ฉด {isActive: true} ์ผ์นํ์ง ์์ผ๋ฉด {isActive: false}
className
className
์กฐ๊ฑด์ ๋ฐ๋ก ์ง์ ํ์ง ์์๋ค๋ฉด, ๊ฒฝ๋ก๊ฐ ์ผ์นํ ๋(ํ์ฑํ ์ํ) active
๋ผ๋ ์ด๋ฆ์ ํด๋์ค๊ฐ ์๋์ผ๋ก ์ถ๊ฐ๋๋ค. ์ผ์นํ์ง ์์ ๋ ๋น ๋ฌธ์์ด""
๋ก ๋์จ๋ค.
HTML ์๋ฆฌ๋จผํธ โผ
// ๊ฒฝ๋ก๊ฐ ์ผ์นํ ๋ NavLink ์๋ฆฌ๋จผํธ
<a href="/profiles/smith" class="active" aria-current="page">๋งํฌ</a>
// ๊ฒฝ๋ก๊ฐ ์ผ์นํ์ง ์์ ๋ NavLink ์๋ฆฌ๋จผํธ
<a href="/profiles/smith" class="">๋งํฌ</a>
NavLink ์์ ์ฝ๋
ํ์ฑํ ์ํ๋ฉด(to="..."
์ ๋ช
์ํ ๊ฒฝ๋ก์ ํ์ฌ ๊ฒฝ๋ก๊ฐ ์ผ์นํ ๋) red
์คํ์ผ ๋งํฌ์ 'activated'
๋ผ๋ ํด๋์ค ์ด๋ฆ์ ๊ฐ๊ณ , ํ์ฑํ ์ํ๊ฐ ์๋๋ฉด 'deactivated'
๋ผ๋ ํด๋์ค ์ด๋ฆ์ ๊ฐ๋ ์์.
<NavLink
to="smith"
style={({ isActive }) => (isActive ? { color: 'red' } : null)}
className={({ isActive }) => (isActive ? 'activated' : 'deactivated')}
>
Smith(NavLink)
</NavLink>;
end ์์ฑ
ํ์ ๊ฒฝ๋ก๊ฐ ์ผ์นํ๋๋ผ๋ ํด๋น ์ปดํฌ๋ํธ๋ ํ์ฑํ ์ํ๋ก ๋งค์นญ๋์ง ์๋๋ก ํ ๋ end
์์ฑ์ ์ฌ์ฉํ ์ ์๋ค. ์๋ ์์์์ ์น์ฌ์ดํธ ๋ฃจํธ('/'
)์์๋ง ํ์ฑํ๋๊ณ ๋ค๋ฅธ URL์ ํ์ฑํ๋์ง ์๋๋ค. v6 ๋ถํฐ ๊ธฐ๋ณธ์ ์ผ๋ก exact
์ต์
์ด ์ ์ฉ๋๋ฏ๋ก end
์์ฑ์ ๋ฑํ ์ฌ์ฉํ ์ผ์ด ์์ง ์์๊น ์๊ฐํ๋ค.
<NavLink to="/" end>
Home
</NavLink>
useRoutes
v5์์ ๊ฐ์ฒด๋ฅผ ์ด์ฉํด ๊ณ์ธต ๊ตฌ์กฐ๋ก ๋ผ์ฐํธ๋ฅผ ๊ตฌ์ฑํ ๋ react-router-config
๋ผ๋ ํจํค์ง๋ฅผ ์ค์นํด์ผ ํ๋ค. v6๋ถํด React Router์์ ์ ๊ณตํ๋ useRoutes
Hook์ ์ด์ฉํ๋ฉด ๋๋ค.
useRoutes
Hook์ ๊ธฐ๋ฅ์ ์ผ๋ก <Routes>
์ ๋์ผํ์ง๋ง, JSX๋ฅผ ์ฐ์ง ์๊ณ JS ๊ฐ์ฒด ํํ๋ก <Routes>
์๋ฆฌ๋จผํธ๋ฅผ ์ ์ํ ์ ์๋ค. ์ฆ useRoutes([{...}])
ํ๋ผ๋ฏธํฐ์ ๋๊ธฐ๋ {...}
๊ฐ์ฒด๋ <Route>
์๋ฆฌ๋จผํธ์ ๋์ผํ๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
useRoutes
๋ ๋งค์นญํ๋ ๋ผ์ฐํธ๊ฐ ์์ผ๋ฉด React ์๋ฆฌ๋จผํธ๋ฅผ ๋ฐํํ๊ณ , ์๋ค๋ฉด null
์ ๋ฐํํ๋ค. <Routes>
์ useRoutes
๋ ๋์ผํ๋ฏ๋ก ์ ํธํ๋ ๊ฒ์ ์ฌ์ฉํ๋ฉด ๋๋ค. ์๋ ๋ ์ฝ๋๋ ์์ ํ ๋์ผํ๊ฒ ์๋ํ๋ค.
import { useRoutes } from 'react-router-dom';
const App = function () {
const elements = useRoutes([
// Route์์ ์ฌ์ฉํ๋ props์ ๋์ผ
{ path: '/', element: <Home /> },
{ path: '/about', element: <About /> },
{
path: '/profiles',
element: <Profiles />,
children: [
// ์ค์ฒฉ ๋ผ์ฐํธ(์๋ธ ๋ผ์ฐํธ)๋ children ํ๋กํผํฐ ์ฌ์ฉ
{ index: true, element: <div>์ ์ ๋ฅผ ์ ํํด์ฃผ์ธ์</div> },
{ path: ':username', element: <Profile /> },
],
},
]);
return (
<div>
<ul>{/* ์๋ต */}</ul>
{elements}
</div>
);
};
import { Routes, Route } from 'react-router-dom';
const App = function () {
return (
<div>
<ul>{/* ์๋ต */}</ul>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/profiles" element={<Profiles />}>
<Route index element={<div>์ ์ ๋ฅผ ์ ํํด์ฃผ์ธ์ </div>} />
<Route path=":username" element={<Profile />} />
</Route>
</Routes>
</div>
);
};
์ฐธ๊ณ ๋ก NotFound
ํ์ด์ง๋ฅผ ๊ตฌํํ ๋ ์๋์ฒ๋ผ '*'
๊ฒฝ๋ก๋ฅผ ๊ฐ๋ ๊ฐ์ฒด(๋ผ์ฐํธ)๋ฅผ ํ๋ ๋ ์ถ๊ฐํ๋ฉด ๋๋ค
const element = useRoutes([
{ path: '/', element: <Home /> },
// ์๋ต...
{ path: '*', element: <NotFound /> },
]);
๊ณต์ ๋ฌธ์ ์์ ์ฝ๋
- React-router Route Objects Example - StackBlitz
- React-router Auth Example - StackBlitz
- React-router Modal Example - StackBlitz
๋ ํผ๋ฐ์ค
๊ธ ์์ ์ฌํญ์ ๋ ธ์ ํ์ด์ง์ ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ๋ฐ์๋ฉ๋๋ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด ์ฃผ์ธ์
'๐ช Programming' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote
๋ค๋ฅธ ๊ธ
-
[CS] RISC / CISC ์ํคํ ์ฒ ์ฐจ์ด์
[CS] RISC / CISC ์ํคํ ์ฒ ์ฐจ์ด์
2024.05.01 -
[JS] ์๋ฐ์คํฌ๋ฆฝํธ RORO ๋์์ธ ํจํด / ์คํ ํธ๋ ์ด์ค / ์๋ฌ ์ ํ
[JS] ์๋ฐ์คํฌ๋ฆฝํธ RORO ๋์์ธ ํจํด / ์คํ ํธ๋ ์ด์ค / ์๋ฌ ์ ํ
2024.05.01 -
[Algorithm] ํ๋ก๊ทธ๋๋จธ์ค ๋น๋ฐ์ง๋ ๋ฌธ์ ํ์ด
[Algorithm] ํ๋ก๊ทธ๋๋จธ์ค ๋น๋ฐ์ง๋ ๋ฌธ์ ํ์ด
2024.04.30 -
[AWS] EC2 ๋์คํฌ ๊ณต๊ฐ ๋๋ฆฌ๊ธฐ / ์ฌ์ ๊ณต๊ฐ ํ๋ณดํ๊ธฐ
[AWS] EC2 ๋์คํฌ ๊ณต๊ฐ ๋๋ฆฌ๊ธฐ / ์ฌ์ ๊ณต๊ฐ ํ๋ณดํ๊ธฐ
2024.04.30