페이지를 구현할 수 있게 해주는 패키지
yarn add react-router-dom
src/pages/만들페이지컴포넌트.jsx
브라우저에 우리가 URL을 입력하고 이동했을 때 원하는 페이지 컴포넌트로 이동하게 해줌
// src/shared/Router.js
import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import 만든컴포넌트페이지 from '../pages/만든컴포넌트페이지'
// Router 라는 함수를 만들고 아래와 같이 작성
// BrowserRouter를 Router로 감싸는 이유는
// SPA의 장점인 브라우저가 깜빡이지 않고 다른 페이지로 이동할 수 있게 만들어줌
const Router = () => {
return (
<BrowserRouter>
<Routes>
{/*
Route에는 react-router-dom에서 지원하는 props들이 있음
path는 우리가 흔히 말하는 사용하고싶은 "주소"를 넣어줌
element는 해당 주소로 이동했을 때 보여주고자 하는 컴포넌트를 넣음
*/}
<Route path="/" element={<만든컴포넌트페이지 />}>
</Routes>
</BrowserRouter>
);
};
export default Router;
❗ 주의 : react-router-dom에 있는 Router가 아니라 직접 만든 Router를 import
최상위 컴포넌트인 App.js에 Router를 넣어줌
👉 어떤 컴포넌트를 화면에 띄우던 항상 App.js를 거쳐야함
그래서 path별로 분기가 되는 Router.js
를 App.js
에 위치시키고 우리의 서비스를 이용하는 모든 사용자가 항상 App.js → Router.js
를 거치도록 함
import React from "react";
import Router from "./shared/Router";
function App() {
return <Router />;
}
export default App;
리액트에서 useState와 같은 Hook을 제공하는 것처럼 React-router-dom에서도 Hook을 제공함
다른 페이지로 보내고자 할 때 사용
// src/pages/home.js
import { useNavigate } from "react-router-dom";
const Home = () => {
const navigate = useNavigate();
return (
<button
onClick={() => {
navigate("/works");
}}
>
works로 이동
</button>
);
};
export default Home;
현재 위치하고 있는 페이지의 여러가지 정보를 추가적으로 얻을 수 있음
// src/pages/works.js
import { useLocation } from "react-router-dom";
const Works = () => {
const location = useLocation();
console.log("location :>> ", location);
return (
<div>
<div>{`현재 페이지 : ${location.pathname.slice(1)}`}</div>
</div>
);
};
export default Works;
hook은 아니지만 꼭 알아야할 API
html 태그중에a
태그의 기능을 대체하는 API
jsx에서a
태그를 사용해야한다면 반드시Link
를 사용해서 구현해야 함
👉
a
태그 사용 → 페이지가 이동하면서 브라우저가 새로고침 → 모든 컴포넌트 다시 렌더링 & 리덕스나 useState를 통해 메모리상에 구축해놓은 모둔 상태값 초기화 → 성능에 악영향
import { Link, useLocation } from 'react-router-dom';
const Works = () => {
const location = useLocation();
console.log('location :>> ', location);
return (
<div>
<div>{`현재 페이지 : ${location.pathname.slice(1)}`}</div>
<Link to="/contact">contact 페이지로 이동하기</Link>
</div>
);
};
export default Works;
어떤 자식 엘리먼트가 들어올지 미리 예상할 수 없는 경우 범용적인 '박스' 역할을 하는 Sidebar 혹은 Dialog와 같은 컴포넌트에서 특히 자주 볼 수 있음
(여기서 말하는 범용적인 '박스'역할이란 크게 봤을 때 Layout 역할을 하는 컴포넌트)
// src/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',
}
function Header() {
return (
<div style={{ ...HeaderStyles }}>
<span>Sparta Coding Club - Let's learn React</span>
</div>
);
}
function Footer() {
return (
<div style={{ ...FooterStyles }}>
<span>copyright @SCC</span>
</div>
);
}
function Layout({ children }) {
return (
<div>
<Header />
<div style={{...layoutStyles}}>
{children}
</div>
<Footer />
</div>
);
}
export default Layout;
// src/shared/Router.js
import React from 'react';
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 Layout from './Layout';
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 />} />
</Routes>
</Layout>
</BrowserRouter>
);
};
export default Router;