๐บ React ๋ผ์ฐํฐ์ ๋ํด ์์๋ณด๊ธฐ ์ ์ SPA ์ ๊ฐ๋ ์ ๋ํด ์์๋ณด์.
๐ SPA๋? (single page application)
ํ๋์ ํ์ด์ง๋ก ๋ง๋ค์ด์ง ์ดํ๋ฆฌ์ผ์ด์ ์ ์๋ฏธํ๋ค.
์ ํต์ ์ธ ๋ฐฉ์์ Server๊ฐ html ํ์ผ ๋ง๋ค๊ณ data ์ค์ด์ ์๋ตํ์ง๋ง,
spa ๋ฐฉ์์ ํด๋ผ์ด์ธํธ์ html ์ธ์๋๊ณ ๋ฐ์ดํฐ๋ง ์์ฒญ์๋ต์ ํตํด ๋ฐ๊พผ๋ค.
- SPA๋ htmlํ์ผ์ ๋ธ๋ผ์ฐ์ ์ธก์์ ๋ก๋ํ๊ณ , ํ์ํ ๋ฐ์ดํฐ๋ API์ ajaxํต์ ์ ์ด์ฉํด์ ์ฒ๋ฆฌํฉ๋๋ค.
- ๋ธ๋ผ์ฐ์ ์์ ์ฌ์ฉ์๊ฐ ์ํธ์์ฉ ํ๋ฉด ํ์ํ ๋ถ๋ถ๋ง ์ ๋ฐ์ดํธ ํด์ ์ฒ๋ฆฌํฉ๋๋ค.
- ๋ฉํฐํ๋ซํผ Android, IOS์ ๋์ํ์ฌ ์น๋ทฐ๋ก ์ฒ๋ฆฌํ๋ ๋ชฉ์ ์ผ๋ก๋ ์ฌ์ฉ๋ฉ๋๋ค.
๐ SPA์ ๋จ์ (CSR๋ฐฉ์)
- ์ฑ์ ๊ท๋ชจ๊ฐ ์ปค์ง๋ฉด, JSํ์ผ๋ ๋๋ฌด ์ปค์ ธ์ ๋ก๋ฉ์ด ์ค๋๊ฑธ๋ฆฌ๊ฒ ๋ฉ๋๋ค.
- ๋ธ๋ผ์ฐ์ ์์ ๋ ๋๋ง์ด ์๋ฃ๋๊ธฐ ๊น์ง ๋น์ด์๋ ํ๋ฉด์ด ๋์ค๊ฒ ๋ฉ๋๋ค.
- ๊ทธ๋์ ๊ท๋ชจ๊ฐ ํฐ ์ดํ๋ฆฌ์ผ์ด์ ์ SSR(์๋ฒ์ฌ์ด๋ ๋ ๋๋ง) ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค. (์นํฉ ์ค์ ํ์)
๐บ ์ด์ ๋ผ์ฐํ ์ ๋ํด ์์๋ณด์. !
๐ ๋ผ์ฐํ ์ด๋?
- ๋ธ๋ผ์ฐ์ ์ ์ฃผ์์ํ์ ๋ฐ๋ผ ๋ค์ํ ํ๋ฉด์ ๋ณด์ฌ์ฃผ๋๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ ๋ผ์ฐํ ์ด๋ผ๊ณ ํฉ๋๋ค.
๐ ์ฌ์ฉ์ด์
- create-react-app๋ก ํ๋ก์ ํธ๋ฅผ ์์ฑํ๊ฒ ๋๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก SPA์ CSR(ํด๋ผ์ด์ธํธ ๋ ๋๋ง) ์ ๋๋ค.
- ํ๋์ ํ์ด์ง๋ง ์ฌ์ฉํ๊ฒ ๋๋ ๊ฒ์ ๋๋ค.
- SPA์ด์ง๋ง ๋ผ์ฐํฐ๋ฅผ ํ์ฉํด์ ์ฌ์ฉ์๋ก ํ์ฌ๊ธ ์ฌ๋ฌ ํ์ด์ง๊ฐ ์กด์ฌํ๋ ๊ฒ์ฒ๋ผ ๋๊ปด์ง๊ฒ ํ ์ ์์ต๋๋ค.
๐บ ๋ผ์ฐํฐ๋ ์ค์นํด์ ์ฌ์ฉํด์ผํ๋ค!
๐ ๋ฆฌ์กํธ ๋ผ์ฐํฐ ์ค์น ๋ฐฉ๋ฒ
1.๋ผ์ฐํฐ๋ฅผ ์ ์ฉํ ํ๋ก์ ํธ ์์ฑ
npm create react-app ํ๋ก์ ํธ๋ช
2.๋ผ์ฐํฐ ์ค์น
npm install react-router-dom
3. ํ๋ก์ ํธ ์์
npm start
๐ ๋ผ์ฐํฐ ์ ์ฉํ๊ธฐ
- ๋ผ์ฐํฐ๋ฅผ ์ฌ์ฉํ ๋๋ root app ์ต์์ ์ปดํฌ๋ํธ index.js์์ App์ปดํฌ๋ํธ๋ฅผ <BrowserRouter>๋ก ๊ฐ์ธ์ค๋๋ค.
- ํ์ด์ง ์ปดํฌ๋ํธ ๋ง๋ค๊ธฐ
- App์ปดํฌ๋ํธ์์ <Routes>๋ฅผ ์ฌ์ฉํด์ ๋ถ๊ธฐํ๊ธฐ
- ์ฃผ์์์ฒญ์ ํตํด ํ์ธํ๊ธฐ
๐บ ๋ผ์ฐํฐ ์ข ๋ฅ๋ ์ด๋ค ๊ฒ์ด ์์๊น?
- <Routes>: ๋ชจ๋ Route ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ธ๋ ์ปจํ ์ด๋ ์ปดํฌ๋ํธ์ ๋๋ค. Route ์ปดํฌ๋ํธ๋ ์์์ผ๋ก ๋ฐ์์ ๋ผ์ฐํ ์ ์ ์ํฉ๋๋ค.
- <Route>: ๊ฒฝ๋ก์ ํด๋น ๊ฒฝ๋ก์ ๋ ๋๋งํ ์ปดํฌ๋ํธ๋ฅผ ์ ์ํฉ๋๋ค. ์ค์ฒฉ ๋ผ์ฐํธ๋ฅผ ์ง์ํ๋ฉฐ, element ์์ฑ์ผ๋ก ๋ ๋๋งํ JSX ์์๋ฅผ ์ ๋ฌํฉ๋๋ค.
- <Navigate>: ํ์ด์ง๋ฅผ ๋ฆฌ๋ค์ด๋ ํธํ๋ ์ปดํฌ๋ํธ์ ๋๋ค. to ์์ฑ์ผ๋ก ์ด๋ํ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ๊ณ , replace ์์ฑ์ผ๋ก ํ์ฌ ํ์ด์ง๋ฅผ ๊ต์ฒดํ ์ ์์ต๋๋ค.
- <Link>: ํ์ด์ง ๊ฐ ๋ค๋น๊ฒ์ด์ ์ ์ํ ๋งํฌ๋ฅผ ์์ฑํฉ๋๋ค. to ์์ฑ์ผ๋ก ์ด๋ํ ๊ฒฝ๋ก๋ฅผ ์ง์ ํฉ๋๋ค.
- <NavLink>: ํ์ฑ ๋งํฌ ์คํ์ผ๋ง์ ์ง์ํ๋ ๋งํฌ ์ปดํฌ๋ํธ์ ๋๋ค. to ์์ฑ์ผ๋ก ์ด๋ํ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ๊ณ , isActive ์์ฑ์ผ๋ก ํ์ฑ ์ํ์ ๋ํ ์คํ์ผ์ ์ ์ฉํ ์ ์์ต๋๋ค.
- <Outlet>: ์ค์ฒฉ ๋ผ์ฐํธ์ ์์ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋๋ ์๋ฆฌ์ ๋๋ค. ๋ถ๋ชจ ๋ผ์ฐํธ์ ์ปดํฌ๋ํธ ๋ด์์ ์ฌ์ฉ๋ฉ๋๋ค.
- useNavigate: ํ๋ก๊ทธ๋จ์ ์ผ๋ก ๋ค๋น๊ฒ์ด์ ์ ์ฒ๋ฆฌํ๋ ํ ์ ๋๋ค. navigate ํจ์๋ฅผ ํธ์ถํ์ฌ ํ์ด์ง๋ฅผ ์ด๋ํฉ๋๋ค.
- useParams: URL ํ๋ผ๋ฏธํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ํ ์ ๋๋ค. URL์์ ๋์ ์ผ๋ก ๊ฐ์ ์ฝ์ด์ฌ ์ ์์ต๋๋ค.
- useLocation: ํ์ฌ ์์น ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ ํ ์ ๋๋ค. ํ์ฌ URL, ๊ฒ์ ํ๋ผ๋ฏธํฐ, ์ํ ๋ฑ์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
- useSearchParams: ์ฟผ๋ฆฌ ๋ฌธ์์ด์ ๊ฒ์ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ์ค์ ํ๋ ํ ์ ๋๋ค.
<Link> ๋ฅผ ์ด์ฉํด์ ๋ค๋ฅธ ํ์ด์ง๋ก ์ด๋
[App.js]
import {Route, Routes} from 'react-router-dom';
import Home from './component/Home';
import Info from './component/Info';
import User from './component/User';
import Board from './component/Board';
import BoardContent from './component/BoardContent';
import Header from './layout/Header';
import MyPage from './component/MyPage';
function App() {
return (
// ์ค์ฒฉ๋ผ์ฐํฐ
<Routes>
<Route element={<Header/>}>
<Route path='/' element={<Home/>} />
<Route path='/info/:num' element={<Info/>} />
<Route path='/user' element={<User/>} />
</Route>
{/* <Route path='/board' element={<Board/>} />
<Route path='/board/:num' element={<BoardContent/>} /> */}
{/* ์ค์ฒฉ ๋ผ์ฐํฐ */}
<Route path='/board' element={<Board/>}>
<Route path=':num' element={<BoardContent/>} />
</Route>
{/* navigation ์ปดํฌ๋ํธ */}
<Route path='/mypage' element={<MyPage/>} />
</Routes>
);
}
export default App;
[home.js]
import { Link } from "react-router-dom";
function Home() {
return (
<div>
<h3>ํํ์ด์ง ์
๋๋ค</h3>
<Link to='/user?name=ํ๊ธธ๋&age=20'>userํ์ด์ง</Link>
<br/>
<Link to='/info/1'>infoํ์ด์ง</Link>
<Link to='/info/2'>infoํ์ด์ง</Link>
<Link to='/info/3'>infoํ์ด์ง</Link>
</div>
)
}
export default Home;
- <Link> ์ปดํฌ๋ํธ: React Router์์ ์ ๊ณตํ๋ ์ปดํฌ๋ํธ๋ก, SPA(Single Page Application)์์ ํ์ด์ง ์๋ก๊ณ ์นจ ์์ด ๋ค๋ฅธ ํ์ด์ง๋ก ์ด๋ํ ์ ์๊ฒ ํด์ค๋๋ค.
- to='/info/1': to ์์ฑ์ ์ด๋ํ ๋์ ๊ฒฝ๋ก(URL)๋ฅผ ์ ์ํฉ๋๋ค. ์ด ๊ฒฝ์ฐ, ๋งํฌ๋ฅผ ํด๋ฆญํ๋ฉด /info/1 ๊ฒฝ๋ก๋ก ์ด๋ํ๊ฒ ๋ฉ๋๋ค.
URL ํ๋ผ๋ฏธํฐ์ ์ฟผ๋ฆฌ์คํธ๋ง
๐บ ๊ฐ์ ๋๊ฒจ์ฃผ๋ ๋ฐฉ์์ urlํ๋ผ๋ฏธํฐ , ์ฟผ๋ฆฌ์คํธ๋ง์ด ์๋ค.
๊ฐ์ ์ปดํฌ๋ํธ๋ผ๋ ์ ๋ฌ๋๋ ๋ฐ์ดํฐ์ ๋ฐ๋ผ์ ๋ค๋ฅธ ๋ด์ฉ์ ๋ณด์ฌ์ค์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
EX) ๊ธ ์์ธ
์ด ๋ URL์ฃผ์์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ฌ ํ ์ ์๊ณ , ์ปดํฌ๋ํธ๋ ๊ทธ ๊ฐ์ ๋ฐ์์ ์ฌ์ฉ ํ ์ ์์ต๋๋ค.
๐บ ์ฟผ๋ฆฌ์คํธ๋ง ( /๊ฒฝ๋ก?ํค=๊ฐ&ํค=๊ฐ)
- ์ฟผ๋ฆฌ์คํธ๋ง์ ์ฃผ์์ ? ๋ค์ ํค=๊ฐ ์ ํํ๋ก ๋์ด๊ฐ๋ ๋งค๊ฐ๊ฐ์ ๋๋ค.
- ๋ณ๋์ ๋ผ์ฐํฐ ์ค์ ์ ํ์ง ์์๋ ๋ฉ๋๋ค.
- ์ปดํฌ๋ํธ์์๋ useLocation() ํ or useSearchParams() ํ ์ ์ฌ์ฉ ํด์ ์ฟผ๋ฆฌ์คํธ๋ง์ ๋ฐ์ ์ ์์ต๋๋ค.
๐บ ๋งํฌ์์
๐ /๊ฒฝ๋ก?ํค=๊ฐ&ํค=๊ฐ
<Link to='/user?name=ํ๊ธธ๋&age=20'>userํ์ด์ง</Link>
๐บ์ปดํฌ๋ํธ์์
๐ useLocation() ํ
const location = useLocation();
- useLocation() ํ : React Router์์ ํ์ฌ URL์ ๋ํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ ํ
- pathname: ํ์ฌ ๊ฒฝ๋ก (์: /info/1)
- search: ์ฟผ๋ฆฌ ๋ฌธ์์ด (์: ?name=John&age=30)
- hash: URL์ ํด์ ๋ถ๋ถ (์: #section1)
- state: Link ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํด ๊ฒฝ๋ก๋ฅผ ๋ณ๊ฒฝํ ๋ ์ ๋ฌํ ์ํ ๊ฐ์ฒด
๐ useSearchParams() ํ
const [๊ฐ์ฒด, function] = useSearchParams()
- ๋ฐฐ์ด์ ๋ฐํํฉ๋๋ค.
- ์ฒซ ๋ฒ์งธ ์์๋ ์ฟผ๋ฆฌํ๋ผ๋ฏธํฐ๋ฅผ ์กฐํํ๊ฑฐ๋ ์์ ํ๋ get, set์ด ๋ด๊ธด ๊ฐ์ฒด
- ๋ ๋ฒ์งธ ์์๋ ์ฟผ๋ฆฌํ๋ผ๋ฏธํฐ๋ฅผ ๊ฐ์ฒด๋ก ์ ๋ฐ์ดํธ ํ๋ ํจ์ ๋ฐํ
- useSearchParams() ํ : React Router์์ URL์ ์ฟผ๋ฆฌ ๋ฌธ์์ด(search parameters)์ ์ฝ๊ณ ์ค์ ํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ํ (Hook)
- [searchParams, setSearchParams]์ ํํ๋ก ๊ฐ์ ๋ฐํ !
- searchParams.get('query'): query๋ผ๋ ์ด๋ฆ์ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ ๊ฐ์ ๊ฐ์ ธ์ต๋๋ค
const [obj, setObj] = useSearchParams();
let id = obj.get("id");//request.getParameter("ํค")
let key = obj.get("key");
๐บ URLํ๋ผ๋ฏธํฐ (/๊ฒฝ๋ก/๊ฐ/๊ฐ) ๐
- URLํ๋ผ๋ฏธํฐ๋ ์ฃผ์ ๋ค์ /๊ฒฝ๋ก/๊ฐ/๊ฐ ์ ํํ๋ก ๋์ด๊ฐ๋ ๋งค๊ฐ๊ฐ์ ๋๋ค.
- ๋ผ์ฐํฐ์ ์ถ๊ฐ์ ์ธ ์ค์ ์ด ํ์ํฉ๋๋ค. ( /์ฃผ์/:ํค )
- ์ปดํฌ๋ํธ์์๋ useParams() ํ ์ ์ฌ์ฉํ์ฌ URLํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ์ ์ ์์ต๋๋ค.
๐บ ๋ผ์ฐํฐ์์
<Routes>
.....
<Route path='/info/:num' element={<Info/>}/>
</Routes>
๐บ๋งํฌ์์
<li><Link to='/info/1'>1๋ฒ info</Link></li>
๐บ์ปดํฌ๋ํธ์์
๐ useParams() ํ
/param์๋ link๋ก ๋์ด์จ ํค๊ฐ ๋ด๊ฒจ ์์ต๋๋ค.
let param = useParams();
์ค์ฒฉ๋ผ์ฐํฐ๋ก ๊ณตํต ๋ถ๋ถ ์ฒ๋ฆฌํ๊ธฐ
๐บ ์ค์ฒฉ ๋ผ์ฐํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๊ณตํต ๋ถ๋ถ์ ์ฒ๋ฆฌํ ์ ์๊ฒ๋๋ค.
- ๊ธํ์ด์ง๊ฐ ์๊ณ , ๊ธ์ ๋ฐ๋ฅธ ์์ธํ๋ฉด์ด ์๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค.
- ๋ผ์ฐํฐ์ ์ค์ ์ ์๋ ์ฒ๋ผ ๋ณด์ฌ์ง ์ ์์ต๋๋ค.
- ์๋ ์ค์ ์ ๋ ๋ผ์ฐํฐ๊ฐ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ๊ฐ๊ฐ ๋ค๋ฅธ ํ๋ฉด์ด ๋ณด์ ๋๋ค.
๐บ ์ค์ฒฉ ๋ผ์ฐํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ผ์ฐํธ ๋ด์ ๋ค๋ฅธ ๋ผ์ฐํธ๋ฅผ ์ ์ํ ์ ์์ด
๋ณต์กํ URL ๊ตฌ์กฐ๋ฅผ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์๋ค !
- <Routes>: ๋ชจ๋ ๋ผ์ฐํธ๋ฅผ ๊ฐ์ธ๋ ์ปจํ ์ด๋ ์ปดํฌ๋ํธ์ ๋๋ค. Route ์ปดํฌ๋ํธ๋ฅผ ์์์ผ๋ก ๋ฐ์ ๋ผ์ฐํ ์ ์ค์ ํฉ๋๋ค.
- <Route>: ๊ฒฝ๋ก์ ํด๋น ๊ฒฝ๋ก์ ๋ ๋๋งํ ์ปดํฌ๋ํธ๋ฅผ ์ ์ํฉ๋๋ค. ์ค์ฒฉ๋ Route๋ฅผ ์ฌ์ฉํ์ฌ ํ์ ๋ผ์ฐํธ๋ฅผ ์ ์ํ ์ ์์ต๋๋ค.
- element: ๋ ๋๋งํ ์ปดํฌ๋ํธ๋ฅผ ์ง์ ํฉ๋๋ค. JSX ์์๋ฅผ ์ ๋ฌํฉ๋๋ค.
- path: ๋ผ์ฐํธ ๊ฒฝ๋ก๋ฅผ ์ง์ ํฉ๋๋ค. ์ค์ฒฉ ๊ฒฝ๋ก๋ ๋ถ๋ชจ Route์ ๊ฒฝ๋ก๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํฉ๋๋ค.
- <Outlet>: ์ค์ฒฉ๋ ๋ผ์ฐํธ์ ์ฝํ ์ธ ๊ฐ ๋ ๋๋ง๋๋ ์๋ฆฌ์ ๋๋ค. ๋ถ๋ชจ ๋ผ์ฐํธ์ ์ปดํฌ๋ํธ ๋ด์ ์์นํฉ๋๋ค.
๐ ์ค์ฒฉ๋ผ์ฐํฐ
Routes์ Route๋ฅผ ์ฌ์ฉํ์ฌ ๋ณต์กํ ๋ผ์ฐํธ ๊ตฌ์กฐ๋ฅผ ๊ตฌ์ฑํ ์ ์์ผ๋ฉฐ, ์ค์ฒฉ๋ Route๋ ๋ถ๋ชจ ๋ผ์ฐํธ์ ์ฝํ ์ธ ๋ด์ ์์ ์ฝํ ์ธ ๋ฅผ ๋ ๋๋ง
- <Outlet>: ์ค์ฒฉ๋ ๊ฒฝ๋ก์ ์ฝํ ์ธ ๊ฐ ๋ ๋๋ง๋ ์์น๋ฅผ ์ ์ํฉ๋๋ค.
- ๋์ ๊ฒฝ๋ก: URL ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋์ ์ผ๋ก ๊ฒฝ๋ก๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
<Routes>
<Route path='/board' element={<Board/>}/>
<Route path='/board/:num' element={<BoardContent/>}/>
</Routes>
- ๋ง์ฝ Board ๋ชฉ๋ก ํ์ด์ง๋ฅผ ๊ณตํต์ผ๋ก ์ฌ์ฉํ๊ณ ์์ธํ์ด์ง๋ฅผ ์๋ธ๋ก ๋ณด์ฌ์ฃผ๋๋ก ์ฒ๋ฆฌํ๋ ค๋ฉด ์ค์ฒฉ๋ผ์ฐํฐ๋ฅผ ํ์ฉํ ์ ์์ต๋๋ค.
- ์ค์ฒฉ๋ผ์ฐํฐ๋ก ์ ์ฉ๋๋ฉด ๋ถ๋ชจ์ปดํฌ๋ํธ์์ <Outlet> ์ปดํฌ๋ํธ๋ฅผ ํ์ฉํด์ ํ์ ๋ผ์ฐํฐ๋ฅผ ๋ณด์ฌ์ง๊ฒ ํ ์ ์์ต๋๋ค.
<Routes>
<Route path='/board' element={<Board/>}>
<Route path=':num' element={<BoardContent/>}/>
</Route>
</Routes>
๋ผ์ฐํฐ ๋ถ๊ฐ ๊ธฐ๋ฅ (Link, Navigate)
๐บ NavLink ์ปดํฌ๋ํธ
- ๋งํฌ์์ ์ฌ์ฉํ๋ ๊ฒฝ๋ก๊ฐ ๋ผ์ฐํฐ์ ๊ฒฝ๋ก์ ์ผ์นํ๋ฉด ํน์ ์คํ์ผ์ ์ ์ฉ (ํ์ฑํ๊ธฐ๋ฅ)
- NavLink๋ ๋งํฌ์ ๊ฒฝ๋ก๊ฐ ๋ผ์ฐํฐ์ ๊ฒฝ๋ก์ ์ผ์นํ๋ฉด ํน์ ์คํ์ผ์ ์ ์ฉํด ์ค๋๋ค.
- NavLink๋ style์์ฑ์ ์ ๊ณตํฉ๋๋ค
- style์์ฑ์๋ ์คํ์ํฌ ํจ์๋ฅผ ์์ฑํฉ๋๋ค.
- ์ด ํจ์์ ๋งค๊ฐ๋ณ์๋ก {isActive : boolean}๊ฐ์ฒด๋ฅผ ๋ฃ์ด์ฃผ๋๋ฐ, ํ์ฑํ ์ฌ๋ถ๋ฅผ ํ์๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
- ์ฌ์ฉ์ ๋ฐ๋์ {isActive}๋ณ์๋ก ๊ตฌ์กฐ๋ถํดํ ๋น ํฉ๋๋ค.
๐ Link
Link๋ ๊ธฐ๋ณธ์ ์ธ ๋ค๋น๊ฒ์ด์
์ ๊ตฌํํ๋ ๋ฐ ์ฌ์ฉ
๐ NavLink
NavLink๋ Link์ ํ์ฅ์ผ๋ก, ํ์ฌ ํ์ด์ง์์ ์ผ์น ์ฌ๋ถ์ ๋ฐ๋ผ ๋์ ์ผ๋ก ์คํ์ผ์ ์ ์ฉํ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณต
๐บ useNavigate() ํ vs Navigate ์ปดํฌ๋ํธ
๐ useNavigate() ํ
let navigator = useNavigate();
- JS์ history๊ฐ์ฒด๋ฅผ ๋์ ํฉ๋๋ค.
- ์ด๋ฒคํธ์์ ์ฌ์ฉ
- useNavigateํ ์ ํน์ event๊ฐ ๋ฐ์ํ ๋, url์ ์กฐ์ํ ์ ์๋ ํจ์๋ฅผ ์ ๊ณตํฉ๋๋ค.
- react v6 ์์ useHistory ๊ฐ ๋ณํํ ๊ฒ์ ๋๋ค. (JS์ history๊ฐ์ฒด๋ฅผ ๋์ ํฉ๋๋ค)
- JS์ history๋ฅผ ๋ค๋ฃจ๋ ๊ธฐ๋ฅ๋ ์ ๊ณตํฉ๋๋ค.
- ํธ์ถ ์์น: ํจ์ํ ์ปดํฌ๋ํธ ๋ด์์ ํธ์ถํฉ๋๋ค
- ์ฌ์ฉ ๋ฐฉ๋ฒ: ๋ค๋น๊ฒ์ด์ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก๊ทธ๋๋ฐ์ ์ผ๋ก ์ด๋ํฉ๋๋ค.
- ์ฅ์ : ์ฌ์ฉ์ ์ธํฐ๋์ (๋ฒํผ ํด๋ฆญ ๋ฑ)๊ณผ ๊ฐ์ ์ด๋ฒคํธ์์ ๋ค๋น๊ฒ์ด์ ์ ์ํํ ๋ ์ ์ฉํฉ๋๋ค
๐ Navigate ์ปดํฌ๋ํธ
- ๋ฆฌ๋ค์ด๋ ํธ๊ธฐ๋ฅ
- ๋ ๋๋ง์์ ์ฌ์ฉ
- <Navigate> ์ปดํฌ๋ํธ๋ ๋ ๋๋ง ๋ ๋ ํ์ฌ ์์น๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค. (๋ ๋๋ง ์ค ๋ง๋๊ฒ ๋๋ฉด, ํ์ด์ง๋ฅผ ๊ฐ์ ๋ก ์ด๋์ํด)
- useNavigate()ํ ๊ณผ ๋น์ทํด๋ณด์ด์ง๋ง useNavigate()ํ ์ ๋ ๋๋ง ๊ณผ์ ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ํธ์ถ ์์น: JSX ๋ด์์ ์ง์ ๋ ๋๋งํฉ๋๋ค.
- ์ฌ์ฉ ๋ฐฉ๋ฒ: ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋ ๋ ์๋์ผ๋ก ํ์ด์ง๋ฅผ ๋ฆฌ๋ค์ด๋ ํธํฉ๋๋ค.
- ์ฅ์ : ์กฐ๊ฑด๋ถ ๋ฆฌ๋ค์ด๋ ์ ์ด๋, ๋ ๋๋ง ์์ ์์ ๋ค๋น๊ฒ์ด์ ์ ๊ตฌํํ ๋ ์ ์ฉํฉ๋๋ค.
- to: ์ด๋ํ ๊ฒฝ๋ก๋ฅผ ์ง์ ํฉ๋๋ค. ๋ฌธ์์ด ๋๋ ๊ฒฝ๋ก ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- replace: true๋ก ์ค์ ํ๋ฉด ํ์ฌ ํ์ด์ง๋ฅผ ํ์คํ ๋ฆฌ ์คํ์ ์ต์์์์ ๊ต์ฒดํฉ๋๋ค. ์ด๋ ๋ธ๋ผ์ฐ์ ์ "๋ค๋ก ๊ฐ๊ธฐ" ๋ฒํผ์ ์ฌ์ฉํ์ฌ ์ด์ ํ์ด์ง๋ก ๋์๊ฐ ์ ์๊ฒ ๋ง๋ญ๋๋ค. ๊ธฐ๋ณธ๊ฐ์ false์ ๋๋ค.
- state: ์ด๋ํ ํ์ด์ง์ ์ํ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค. ์ด ์ํ๋ location.state๋ฅผ ํตํด ์ ๊ทผํ ์ ์์ต๋๋ค
[user.js]
import { useSearchParams } from "react-router-dom";
function User() {
//1. useLocationํ
์ ์ฌ์ฉ
// const location = useLocation();
// const {search, pathname} = location;
// console.log(search);
// console.log(pathname);
//2. useSearchParamsํ
์ ์ฌ์ฉ
const searchParam = useSearchParams();
console.log(searchParam);
const [obj, setObj] = useSearchParams();
console.log(obj);
console.log(setObj);
let name = obj.get("name");
let age = obj.get("age");
console.log(name, age);
const handleClick = () => {
setObj({name : '์ด์์ ', age : 30}); // ๊ฐ ๋ณ๊ฒฝํ๊ธฐ
}
return (
<div>
<h3>์ ์ ํ์ด์ง ์
๋๋ค</h3>
<button onClick={handleClick}> uri ๊ฐ ๋ณ๊ฒฝ </button>
</div>
)
}
export default User;
- useLocation() ํ : React Router์์ ํ์ฌ URL์ ๋ํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ ํ
//2. useSearchParamsํ
์ ์ฌ์ฉ
const searchParam = useSearchParams();
console.log(searchParam);
const [obj, setObj] = useSearchParams();
console.log(obj);
let name = obj.get("name");
let age = obj.get("age");
console.log(name, age);
- useSearchParams() ํ : React Router์์ URL์ ์ฟผ๋ฆฌ ๋ฌธ์์ด(search parameters)์ ์ฝ๊ณ ์ค์ ํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ํ (Hook)
- [searchParams, setSearchParams]์ ํํ๋ก ๊ฐ์ ๋ฐํ !
- searchParams.get('query'): query๋ผ๋ ์ด๋ฆ์ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ ๊ฐ์ ๊ฐ์ ธ์ต๋๋ค
const handleClick = () => {
setObj({name : '์ด์์ ', age : 30}); // ๊ฐ ๋ณ๊ฒฝํ๊ธฐ
}
- seobj ๋ฅผ ํตํด์ uri ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ค.
[info.js]
import { useParams } from "react-router-dom";
function Info() {
//์์๋ฐ์ดํฐ
const data = {
"1" : {id:1 , name: "ํ๊ธธ๋"},
"2" : {id:2 , name: "์ด์์ "},
"3" : {id:3 , name: "์ ์ฌ์๋น"}
}
//useParamsํ
- URLํ๋ผ๋ฏธํฐ
let param = useParams();
console.log(param);
console.log(param.num); //์ฐพ์์ ์ฌ์ฉํจ
const {id, name} = data[param.num];
return (
<div>
<h3>Infoํ์ด์ง ์
๋๋ค</h3>
<div>
์ ํ๋ ๋ฐ์ดํฐ๋ {id}์ด๊ณ {name}์
๋๋ค.
</div>
</div>
)
}
export default Info;
const data = {
"1" : {id:1 , name: "ํ๊ธธ๋"},
"2" : {id:2 , name: "์ด์์ "},
"3" : {id:3 , name: "์ ์ฌ์๋น"}
}
- ํค:๊ฐ{ํค:๊ฐ, ํค:๊ฐ} ํํ๋ก ๋ค์ด๊ฐ์๋ data ๊ฐ์ฒด
let param = useParams();
console.log(param);
console.log(param.num); //์ฐพ์์ ์ฌ์ฉํจ
const {id, name} = data[param.num];
- useParams() ํ : React Router์์ ์ฌ์ฉ๋๋ ํ ์ผ๋ก, URL ๊ฒฝ๋ก์ ํฌํจ๋ ๋งค๊ฐ๋ณ์(params)๋ฅผ ์ฝ๋ ๋ฐ ์ฌ์ฉ
- param.num ์ ๊ฐ๊ณผ ๋์ํ๋ data ํค๋ฅผ ์ฐพ๊ณ ๊ทธ ๊ฐ์ ํด๋น ํญ๋ชฉ์ id์ name ์์ฑ์ ์ถ์ถ
[info/1]
[info/2]
[info/3]
[header.js]
import { Outlet, useNavigate } from 'react-router-dom';
import style from './Header.module.css';
function Header() {
let nav = useNavigate();
const goBack = () => {
nav(-1);
}
const goHome = () => {
nav('/');
}
return (
<>
<header className={style.wrap}>
<h3> ํค๋์
๋๋ค. </h3>
<ul className={style.wrap_list}>
<li> ๋ชฉ๋ก </li>
<li> ๋ชฉ๋ก </li>
<li> ๋ชฉ๋ก </li>
<li> ๋ชฉ๋ก </li>
</ul>
<div>
<button onClick={goHome}> ํ์ผ๋ก </button>
<button onClick={goBack}> ๋ค๋ก๊ฐ๊ธฐ </button>
</div>
</header>
<section>
<Outlet />
</section>
</>
)
}
export default Header;
- useNavigate () ํ : react-router-dom ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ ๊ณตํ๋ฉฐ, ๋ค๋น๊ฒ์ด์ (ํ์ด์ง ์ด๋) ๊ธฐ๋ฅ์ ์ ๊ณต
- ์ด ํ ์ ๋ค๋น๊ฒ์ด์ ํจ์ nav๋ฅผ ๋ฐํ
- nav(-1)์ ํธ์ถํ์ฌ ๋ธ๋ผ์ฐ์ ์ ํ์คํ ๋ฆฌ ์คํ์์ ํ ๋จ๊ณ ๋ค๋ก ์ด๋
- nav('/')์ ํธ์ถํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฃจํธ ๊ฒฝ๋ก('/')๋ก ์ด๋
[Board.js]
import { Link, NavLink, Outlet } from "react-router-dom";
function Board() {
const myStyle = {color : "green", backgroundColor: "red"};
return (
<>
<h3> ๊ธ ๋ชฉ๋ก </h3>
<ul>
{/* <li><Link to='/board/1'> 1๋ฒ๊ธ </Link></li>
<li><Link to='/board/2'> 2๋ฒ๊ธ </Link></li>
<li><Link to='/board/3'> 3๋ฒ๊ธ </Link></li> */}
<li><NavLink to='/board/1' style={({isActive}) => isActive ? myStyle : undefined }> 1๋ฒ๊ธ </NavLink></li>
<li><NavLink to='/board/2' style={({isActive}) => isActive ? myStyle : undefined }> 2๋ฒ๊ธ </NavLink></li>
<li><NavLink to='/board/3' style={({isActive}) => isActive ? myStyle : undefined }> 3๋ฒ๊ธ </NavLink></li>
</ul>
{/* ์ค์ ๋ผ์ฐํฐ์์ ํ์ ์ปดํฌ๋ํธ๋ฅผ ํ์ํจ */}
<Outlet/>
</>
)
}
export default Board;
[BoardContent.js]
import { useParams } from "react-router-dom";
function BoardContent() {
const {num} = useParams();
return (
<>
<h3> ๊ธ ๋ด์ฉ~ </h3>
{num}๋ฒ ๊ธ ์
๋๋ค. ์ถํ ๋คํธ์ํฌ ํต์ ์ฒ๋ฆฌํจ
</>
)
}
export default BoardContent;
- {num} : URL ๊ฒฝ๋ก์ ํฌํจ๋ ๋งค๊ฐ๋ณ์(params)๋ฅผ ์ฝ์ด์ด
style={(isActive)=>{return isActive ? myStyle : undefined ;}}
- NavLink๋ ํ์ฌ ํ์ฑํ๋ ๋งํฌ๋ฅผ ์ฝ๊ฒ ์คํ์ผ๋ง ๊ฐ๋ฅ !
- isActive : NavLink๊ฐ ํ์ฑํ๋์๋์ง๋ฅผ ๋ํ๋ด๋ ๋ถ์ธ ๊ฐ
<Outlet/>
- <Outlet />์ React Router์์ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๋ก, ์ค์ฒฉ ๋ผ์ฐํธ๋ฅผ ๊ตฌํํ ๋ ์์ ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ๋ ๋ฐ ์ฌ์ฉ
[MyPage.js]
import { Navigate, useNavigate } from "react-router-dom";
function MyPage() {
let nav = useNavigate();
let loginYN = false; // ๋ก๊ทธ์ธ์ฒ๋ฆฌ๋ด์ญ๊ด๋ฆฌ๊ฐ
if(!loginYN){
nav('/');
return <Navigate to='/' replace={true}/>
// ํ์คํ ๋ฆฌ๋ฅผ ๋จ๊ธฐ์ง ์์
// ๋ค๋ก๊ฐ๊ธฐ๋ฅผ ๋จ๊ธฐ์ง ์๋๋ค
}
return (
<>
<h3> ๊ถํ ์๋ ์ ์ ๋ง ์ ๊ทผ ๊ฐ๋ฅ </h3>
</>
)
}
export default MyPage;
if(!loginYN){
nav('/');
return <Navigate to='/' replace={true}/>
}
๋ก๊ทธ์ธ์ด ๋์ด์์ง์์ผ๋ฉด
nav('/')
ํ์ผ๋ก ์ด๋ํ๊ฒ๋๋ค.