여러 페이지를 이동할 수 있도록 화면 전환을 돕는 리액트 패키지
패키지 설치 : yarn add react-router-dom
구현 순서
(1) 페이지 컴포넌트 생성
(2) Router.js 생성 및 router 설정 코드
(3) App.js에 Router import 및 적용
파일 구성
Router.js
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Home from "../pages/Home";
import About from "../pages/About";
import Contact from "../pages/Contact";
import Works from "../pages/Works";
import Work from "../pages/Work";
const Router = () => {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
<Route path="works" element={<Works />} />
<Route path="works/:id" element={<Work />} />
</Routes>
</BrowserRouter>
);
};
export default Router;
App.jsx에 import 하여 사용한다.
import "./App.css";
import Router from "./shared/Router";
function App() {
return <Router />;
}
export default App;
이벤트가 발생할 시 다른 페이지로 이동시키기 위해 사용한다.
ex) navigate("/works")
import React from "react";
import { useNavigate } from "react-router-dom";
function Home() {
const navigate = useNavigate();
return (
<div>
Home <br />
<button
onClick={() => {
navigate("/works");
}}
>
works로 이동
</button>
</div>
);
}
export default Home;
import React from "react";
import { useNavigate, } from "react-router-dom";
function Works() {
const location = useLocation();
return (
<div>
<p>{location.pathname}</p>
</div>
);
}
export default Works;
HTML의 a 태그 기능을 대체하는 API이다.
a 태그가 아닌 Link를 사용하는 이유?
-> a 태그를 사용하면 페이지를 이동하면서 브라우저가 새로고침 되기 때문에 불필요한 렌더링이 일어날 수 있기 때문!
import React from "react";
import { Link} from "react-router-dom";
function Works() {
return (
<div>
<Link to="/contact">contact 페이지로 이동하기</Link>
</div>
);
}
export default Works;
children props 특성을 사용하여 개별적으로 존재하는 Header, Footer, Page를 합성하여 UI를 구현할 수 있다.
// shared/Layout.js
import React from 'react';
// 스타일 지정
const HeaderStyles = {
width: '100%',
background: 'black',
height: '50px',
display: 'flex',
alignItems: 'center',
paddingLeft: '20px',
color: 'white',
fontWeight: '600',
};
const FooterStyles = {
width: '100%',
height: '50px',
display: 'flex',
background: 'black',
color: 'white',
alignItems: 'center',
justifyContent: 'center',
fontSize: '12px',
};
const layoutStyles = {
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
minHeight: '90vh',
}
// Header 컴포넌트
function Header() {
return (
<div style={{ ...HeaderStyles }}>
<span>Header</span>
</div>
);
}
// Footer 컴포넌트
function Footer() {
return (
<div style={{ ...FooterStyles }}>
<span>Footer</span>
</div>
);
}
// Header, Footer와 children 값을 받아 UI를 구현하는 Layout 컴포넌트
function Layout({ children }) {
return (
<div>
<Header />
<div style={{...layoutStyles}}>
{children}
</div>
<Footer />
</div>
);
}
export default Layout;
// shared/Router.js
// Layout import
import Layout from "./Layout";
// Layout으로 children으로 받을 컴포넌트를 감싸준다.
const Router = () => {
return (
<BrowserRouter>
<Layout>
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
<Route path="works" element={<Works />} />
<Route path="works/:id" element={<Work />} />
</Routes>
</Layout>
</BrowserRouter>
);
};
동적 라우팅
path에 유동적인 값을 넣어서 특정 페이지로 이동하도록 구현하는 방법
라우터 경로 지정(Router.js)
<Route path="works" element={<Works />} />
<Route path="works/:id" element={<Work />} />
상위 페이지 구현(Works.js)
import { data } from "../shared/data";
function Works() {
return (
<div>
<h3>할일 목록</h3>
{data.map((item) => {
return (
<div key={item.id}>
{item.id}
<Link to={`/works/${item.id}`}>{item.todo}</Link>
</div>
);
})}
</div>
);
}
export default Works;
상세 페이지 구현(Work.js)
라우터를 사용할 때 지정된 파라미터 값을 가져올 수 있도록 하는 Hook
// work.js
import React from "react";
import { useParams } from "react-router-dom";
import { data } from "../shared/data"; // id를 가지고 있는 객체 배열을 저장한 data
function Work() {
const params = useParams();
const foundData = data.find((item) => { // data 객체의 id값을 가져온다.
return item.id === parseInt(params.id); // params에 저장된 id 값과 item.id의 값이 같으면 반환
});
return (
<div>
<h3>할 일: {foundData.todo}</h3>
</div>
);
}
export default Work;