07. 리액트 라우터(React Router)
# What? 이게 뭔데?
- 리액트 라우팅 라이브러리
# Why? 이걸 왜 쓰는데?
- 리액트로 만든 Single Page Application에서 새로고침 없이 페이지간 이동을 하려면 이게 필요함.
# How? 어떻게 쓰는데?
$ npm install react-router-dom
1. BrowserRouter
- 페이지 전환을 할 영역 겉을 BrowserRouter로 감싸야함
(BrowserRouter로 감싸진 영역 내에서만 Link, Route 등을 쓸 수 있음)
@ App.js
import React from 'react';
import {BrowserRouter} from "react-router-dom";
function App() {
return (
<div className="App">
<BrowserRouter>
{/* 여기에 페이지들 들어갈 예정 */}
</BrowserRouter>
</div>
);
}
export default App;
2. Route
- 어떤 경로(path)를 입력받았을 때 어떤 컴포넌트를 불러올지 명시
<Route path="/pageA" component={PageA}/>
-> "http://localhost:3000/pageA" url을 입력받으면 BrowerRouter로 감싼 영역 내에 <PageA />컴포넌트를 뿌려준다는 뜻
@ App.js
import React from 'react';
import {BrowserRouter, Route, Routes} from "react-router-dom";
import PageA from "./PageA";
import PageB from "./PageB";
function App() {
return (
<div className="App">
<BrowserRouter>
{/* 여기에 페이지들 들어갈 예정 */}
<Routes>
<Route exact path="/pageA" element={<PageA/>} />
<Route exact path="/pageB" component={<PageB/>} />
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
@ PageA.jsx
import React, {} from 'react';
const PageA = () => {
return (
<div>
pageA
</div>
);
};
export default PageA;
@ PageB.jsx
import React, {} from 'react';
const PageB = () => {
return (
<div>
pageB
</div>
);
};
export default PageB;
- 데이터도 넘겨주고 싶을 땐 path에 ":파라미터명"
<Route path="/pageA/:title" element={<PageA/>}/>
-> 컴포넌트에서 파라미터값을 받을 땐 match라는 props를 받아서 match.params를 조회해보면 됨.
-> "http://localhost:3000/pageA/테스트페이지"와 같이 url을 입력해줬다면 title로 "테스트페이지"를 받아서 뿌림
@ PageA.jsx
import React, {} from 'react';
const PageA = ({match}) => {
return (
<div>
{match.params.title}
</div>
);
};
export default PageA;
3. Link
- a링크같은 역할, 새로고침 없이 페이지 이동을 시켜주고 싶으면 Link 사용
<Link to="/example">Example 페이지로 이동<Link>
@ App.js
import React from 'react';
import {BrowserRouter, Route, Routes} from "react-router-dom";
import PageA from "./PageA";
import PageB from "./PageB";
function App() {
return (
<div className="App">
<BrowserRouter>
{/* 여기에 페이지들 들어갈 예정 */}
<Routes>
<Route exact path="/pageA/:title" element={<PageA/>} />
<Route exact path="/pageB" element={<PageB/>} />
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
@ PageA.jsx
import React, {} from 'react';
import {Link} from "react-router-dom";
const PageA = ({match}) => {
return (
<div>
{match.params.title}
<div>
<Link to={"/pageB"}>pageB로 이동</Link>
</div>
</div>
);
};
export default PageA;
@ PageB.jsx
import React, {} from 'react';
import {Link} from "react-router-dom";
const PageB = () => {
return (
<div>
pageB
<div>
<Link to={"/pageA/동적타이틀"}>pageA로 이동</Link>
</div>
</div>
);
};
export default PageB;
# Practice 연습
1. PageA, PageB, Favorites로 이동할 수 있는 네비게이션 만들어보기
@ App.js
import React from 'react';
import {BrowserRouter, Route, Routes} from "react-router-dom";
import PageA from "./PageA";
import PageB from "./PageB";
import Favorites from "./Favorites";
import Navigation from './Navigation';
function App() {
return (
<div className="App">
<BrowserRouter>
<Routes>
{/* 여기에 페이지들 들어갈 예정 */}
<Navigation />
<Route exact path="/pageA/:title" element={<PageA/>} />
<Route exact path="/pageB" element={<PageB/>} />
<Route exact path="/favorites" element={<Favorites/>} />
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
@ Navigation.jsx
import React, {} from 'react';
import {Link} from "react-router-dom";
const Navigation = () => {
return (
<div className="navigation">
<div>
<Link to={"/pageA/새로운타이틀"}>PAGE A</Link>
</div>
<div>
<Link to={"/pageB"}>PAGE B</Link>
</div>
<div>
<Link to={"/FAVORITES"}>FAVORITES</Link>
</div>
<br/>
</div>
);
};
export default Navigation;
* 부모로 전달되는 이벤트 막기
부모, 자식한테 모두 onClick이 걸려있으면 자식만 클릭해도 부모까지 click가 일어남. 이런 현상을 막기 위해서는 다음과 같은 작업 필요
event.stopPropagation();
event.preventDefault();
# Problem 과제
- 할일 컴포넌트 클릭 시
- 해당 할일에 대한 자세한 정보를 보여주는 페이지로 이동하기
* axios.get("/todos/조회하려는 todo의 id");와 같은 api 통신으로 원하는 데이터의 정보를 얻을 수 있음.
* 코드참고 : https://github.com/ShinHyungJune/react-course/tree/course-7-router