React는 기본적으로 SPA Single Page Application이다.
페이지 나누는 법
1. 컴포넌트 만들어서 상세페이지 내용 채움
2. 누가 /detail 접속하면 그 컴포넌트를 보여줌.
위와 같이 하면 코드가 너무 길어지기 때문에 라이브러리를 쓴다.
react-router-dom 을 쓴다.
react-router-dom 사용법
npm install react-router-dom
위 명령어로 설치
index.js 가서
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
);
위와 같이 import 이후에 BrowserRouter를 넣어서 만들어줌.
App.js
import { Routes, Route, Link } from 'react-router-dom';
<Routes>
<Route path="/detail" element={<div>상세페이지임</div>}></Route>
<Route></Route>
</Routes>
위와 같이 사용해주면, 해당 element를 path를 읽어와서 출력해주는 것을 볼 수 있다.
라우트 적용한 최종 코드
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import { Button, Container, Nav, Navbar } from 'react-bootstrap';
import bg from './assets/bg.png';
import { useState } from 'react';
import data from './data';
import { Routes, Route, Link } from 'react-router-dom';
function App() {
let [shoes] = useState(data);
return (
<div className="App">
<Navbar bg="dark" variant="dark">
<Container>
<Navbar.Brand href="#home">Young Shopping</Navbar.Brand>
<Nav className="me-auto">
<Nav.Link href="/">Home</Nav.Link>
<Nav.Link href="/detail">상세페이지</Nav.Link>
<Nav.Link href="/about">About</Nav.Link>
</Nav>
</Container>
</Navbar>
<Routes>
<Route
path="/"
element={
<>
<div
className="main-bg"
style={{
backgroundImage: 'url(' + bg + ')',
color: '',
}}
></div>
<div className="contanier">
<div className="row">
{shoes.map((v, k) => {
return (
<Goods
key={k}
shoes={shoes[k]}
imgIndex={k}
></Goods>
);
})}
</div>
</div>
</>
}
></Route>
<Route path="/detail" element={<div>상세페이지임</div>}></Route>
<Route path="/about" element={<div>About페이지</div>}></Route>
</Routes>
</div>
);
}
function Goods(props) {
return (
<div className="col-md-4">
<img
src={`${process.env.PUBLIC_URL}/img/shoes${
props.imgIndex + 1
}.jpg`}
width="80%"
/>
<h4>{props.shoes.title}</h4>
<p>{props.shoes.content}</p>
<p>{props.shoes.price}</p>
</div>
);
}
export default App;
나중에 컴포넌트로 하나씩 묶어서 넣는 것도 좋은 방법이다.
Link태그
<Link to="/">홈</Link>
<Link to="/detail">상세</Link>
위와 같이 사용해서 link를 만들 수 있다.
navigate
훅이란게 있음
그냥 우리가 유용하게 쓸 수 있는 함수같은거라고 생각하면 된다함.
let navigate = useNavigate();
이렇게 담아서
<Nav className="me-auto">
<Nav.Link
onClick={() => {
navigate('/');
}}
>
Home
</Nav.Link>
<Nav.Link
onClick={() => {
navigate('/detail');
}}
>
상세페이지
</Nav.Link>
<Nav.Link
onClick={() => {
navigate('/about');
}}
>
About
</Nav.Link>
</Nav>
위와 같이 사용이 가능하다. 참고로..
navigate(-1);
위와 같이 쓰면 이전 페이지로 넘어가진다고 함.
404 페이지에 대하여
<Route path="*" element={<div>없는페이지요</div>}></Route>
위와 같이 하면 path 가 모든 지정되지 않는 path의 경우 띄워줄 엘리먼트를 지정할 수 있다.
nested routes
<Route path="/about" element={<About></About>}>
<Route path="member" element={<div>멤버임</div>}></Route>
<Route path="location" element={<div> 위치정보</div>}></Route>
</Route>
위와 같이 Route 안에 또 Route를 쓰는걸 의미하며
이를
function About() {
return (
<div>
<h4>회사정보임</h4>
<Outlet></Outlet>
</div>
);
}
위의 컴포넌트 안에 어디에 넣어줄지를 정해줘야하는데 그 들어가는 공간이 Outlet(구멍) 의 위치에 치환된다.
nested routes 언제쓰냐 여러 유사한 페이지가 필요할 때 사용한다.
- Route는 뒤로가기 버튼도 잘 먹기 때문에 유용하다.
상세페이지의 경우 Route가 많아져야 함.
/detail/0
/detail/1
/detail/2
매번 쓸 수 없으니 반복문으로 쓰자.?
router 적으로 해결하는 방법 url 파라미터를 이용하는 방법
/detail/:id
위와 같이 사용하여 detail 뒤에 아무거나 오게 만들어달라는 뜻임.
그러면, 아래와 같이 컴포넌트파일에서 해당 url의 parameter 값을 가져와서 쓸 수 있다.
let { id } = useParams(); // 현재 url의 parameter 정보가 남음
- 파라미터는 여러개를 쓸 수 있다.
/detail/:id/:page
해당 파라미터 가져와서 보여주는 코드 예시