🔎 리액트는 html 파일을 하나만 사용하기 때문에 다른 페이지로 이동하려면, 외부 라이브러리인 라우터를 설치해서 구현하는게 일반적이다
www.도메인주소.com/detail
의 '/' 이후부터가 라우터!
npm install react-router-dom
입력index.js
파일에서 추가 코드 입력import { BrowserRouter } from 'react-router-dom'; // 추가
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter> // 추가
<App />
</BrowserRouter>
</React.StrictMode>
App.js
파일에 아래 컴포넌트들을 import
한다import { Routes, Route, Link } from 'react-router-dom'
App 컴포넌트
의 html 부분에 Routes
태그로 감싼 Route
를 작성한다 <Routes>
<Route path="/" element={<div>메인</div>} />
<Route path="/detail" element={<div>상세</div>} />
</Routes>
🔎 path
이동할 url의 경로 ('/'은 메인, '/detail'은 www.주소.com/detail 페이지)
🔎 element
보여줄 html의 내용
element에는 컴포넌트
로도 넣어줄 수 있다
<Routes>
<Route path="/" element={<Main />} />
<Route path="/detail" element={<Detail />} />
</Routes>
클릭하면 라우터로 이동할 수 있는 링크
<Link to="/">Home</Link>
<Link to="/detail">Detail</Link>
Link보다 깔끔한 함수
import { Routes, Route, Link, useNavigate } from 'react-router-dom';
다른 라우터들과 같이 import
시켜줘야 함
function App() {
let navigate = useNavigate()
return (
<Nav className="me-auto">
<Nav.Link onClick={() => { navigate('/') }}>Home</Nav.Link>
<Nav.Link onClick={() => { navigate('/detail') }}>Detail</Nav.Link>
</Nav>
navigate
라는 변수에 useNavigate()
함수를 할당하고 html 태그에 onClick
함수로 사용한다
라우터 주소가 유효하지 않아서 존재하지 않는 페이지인 경우
<Routes>
<Route path="*" element={<div>없는 페이지</div>} />
</Routes>
Route path
에 "*"
을 입력하면 라우터를 설정하지 않은 이상한 페이지들이 전부 해당됨
라우터 안의 라우터
import { Routes, Route, Link, useNavigate, Outlet } from 'react-router-dom';
Outlet
을 import
시키고 사용한다
<Route path="/event" element={<Event />}>
<Route path="one" element={<div>첫 주문시 양배추즙 서비스</div>} />
<Route path="two" element={<div>생일기념 쿠폰받기</div>} />
</Route>
Event 컴포넌트
를 만들어서 event 라우터
에 연결해준다
function Event() {
return (
<div>
<h4>오늘의 이벤트</h4>
<Outlet></Outlet>
</div>
)
}
동시에 보여지고 싶은 내용의 위치에 Outlet
을 입력한다
event 라우터만 보여졌을 때
event/one 라우터가 보여졌을 때
event/two 라우터가 보여졌을 때
라우터 값과 아이템의 id 통일하기
import { useParams } from "react-router-dom"
function Detail({shoes}) {
let {id} = useParams()
상세페이지 컴포넌트에 useParams
를 import
하고, {id}
변수에 할당해준다
<Routes>
<Route path="/detail/:id" element={<Detail shoes={shoes} />} />
</Route>
App 컴포넌트
내부의 할당해준 path
뒤에 /:id
를 입력하면 www.주소.com/detail/
뒤에 어떤 숫자가 오든 상세페이지를 보여줄 수 있다
근데 상세페이지 라우터와 조회하고자 하는 아이템의 id값을 통일시켜야 고객이 원하는 페이지로 이동할 수 있다
function Detail({shoes}) {
let {id} = useParams()
let shoe = shoes.find((item) => {
return item.id === parseInt(id)
})
return (
그래서 상세페이지 컴포넌트
에 아이템의 id값을 찾는 변수 shoe
를 선언하고, find
메소드를 사용해서 shoes의 id와 useParams의 id가 같은 것을 return하는 함수를 할당한다
return (
// ...생략
<img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%" />
</div>
<div className="col-md-6">
<h4 className="pt-5">{shoe.title}</h4>
<p>{shoe.content}</p>
<p>{shoe.price}원</p>
)
상세페이지 컴포넌트
의 상품명, 가격 등도 변수 shoe로 데이터바인딩
해줘서 라우터의 숫자와 상품의 id가 일치하게 해준다