# react 라우터 설치
npm install react-router-dom@6
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 { Routes, Route, Link } from 'react-router-dom';
이렇게 Route라이브러리 임포트 해주고
<Routes>
<Route path="/detail" element={<div>detail</div>} />
<Route path="/cart" element={<div>cart</div>} />
</Routes>
이렇게 Route태그에다가 path와 element를 넣어주면 element에 있는 태그가 해당 경로에 생긴다.
저기 element는 무쪼건 태그하나로 시작해서 하나로 끝나야한다.
vue에서처럼 ground인 app.js에 있는 html이 뜨고
거기에 추가되는 컴포넌트같음.
이걸 요약할수 있는 기능이 있을거임. 컴포넌트로 할듯
function App() {
const [shoes, setShoes] = useState(products);
return (
<div className="App">
<Navbar bg="light" data-bs-theme="light">
<Container>
<Navbar.Brand href="#home">Muzzi</Navbar.Brand>
<Nav className="me-auto">
<Nav.Link href="/">Home</Nav.Link>
<Nav.Link href="detail">Detail</Nav.Link>
<Nav.Link href="cart">Cart</Nav.Link>
</Nav>
</Container>
</Navbar>
<Routes>
<Route path="/detail" element={<div>detail</div>} />
<Route path="/cart" element={<div>cart</div>} />
<Route
path="/"
element={
<div>
<div
className="main-bg"
style={{ backgroundImage: `url('${bg}')` }}
></div>
<div className="img-box">
{shoes.map((data, index) => {
return <Product key={index} data={data}></Product>;
})}
</div>
</div>
}
/>
</Routes>
</div>
);
}
이렇게 Route에 경로도 설정해주니까 뭐 적용 잘된다.
참고로 만든 html태그를 home에 넣어줬음.
# Link
{/* 링크 */}
<Link to="/">home</Link>
<Link to="/detail">상세</Link>
저렇게 Link쓸수 있음
주석은 저렇게 쓴다.
# 컴포넌트 나누기
const Detail = () => {
return (
<div className="container">
<div className="row">
<div className="col-md-6">
<img
src="https://codingapple1.github.io/shop/shoes1.jpg"
width="100%"
/>
</div>
<div className="col-md-6">
<h4 className="pt-5">상품명</h4>
<p>상품설명</p>
<p>120000원</p>
<button className="btn btn-danger">주문하기</button>
</div>
</div>
</div>
);
};
export default Detail;
Detail.js라는 파일에 컴포넌트 코드를 넣어줌.
그리고 export Detail로 설정.
//App.js에서
import Detail from './Detail.js';
App.js에서 해당 컴포넌트를 import한 후,
<Route path="/detail" element={<Detail />} />
이렇게 태그 갖다 넣어주면 됨.
난 참고로 Detail.js에서 return을 안해서 안됐었음.
상품별로 링크로 들어가는건 파라미터를 배워야할듯.
#파라미터 안쓰고 대충 만들어보기
일단 Detail component에다가 파라미터 만들어줌
const Detail = ({ index, data }) => {
return (
<div className="container">
<div className="row">
<div className="col-md-6">
<img src={data[index].src} width="100%" />
</div>
<div className="col-md-6">
<h4 className="pt-5">{data[index].title}</h4>
<p>{data[index].content}</p>
<p>{data[index].price}</p>
<button className="btn btn-danger">주문하기</button>
</div>
</div>
</div>
);
};
export default Detail;
그리고 app.js에서
//bootstrap
import Button from 'react-bootstrap/Button';
import Container from 'react-bootstrap/Container';
import Nav from 'react-bootstrap/Nav';
import Navbar from 'react-bootstrap/Navbar';
import Card from 'react-bootstrap/Card';
//data
import bg from './img/bg.png';
import products from './products.js';
//native react
import { useState } from 'react';
import './App.css';
//library
import { Routes, Route, Link, useNavigate } from 'react-router-dom';
//component
import Detail from './Detail.js';
function App() {
const navigate = useNavigate();
const [shoes, setShoes] = useState(products);
const [mode, setMode] = useState({
nowIndex: 0,
});
const changeIndex = (i) => {
console.log('muzzi babo');
const copy = { ...mode };
copy.nowIndex = i;
setMode(copy);
navigate('/detail');
};
return (
<div className="App">
<Navbar bg="light" data-bs-theme="light">
<Container>
<Navbar.Brand href="/">Muzzi</Navbar.Brand>
<Nav className="me-auto">
<Nav.Link href="/">Home</Nav.Link>
<Nav.Link href="detail">Detail</Nav.Link>
<Nav.Link href="cart">Cart</Nav.Link>
</Nav>
</Container>
</Navbar>
{/* 링크 */}
<Link to="/">home</Link>
<Link to="/detail">상세</Link>
<Routes>
<Route
path="/"
element={
<div>
<div
className="main-bg"
style={{ backgroundImage: `url('${bg}')` }}
></div>
<div className="img-box">
{shoes.map((data, index) => {
return (
<Product
key={index}
data={data}
onClick={() => {
changeIndex(index);
}}
></Product>
);
})}
</div>
</div>
}
/>
<Route
path="/detail"
element={<Detail index={mode.nowIndex} data={shoes} />}
/>
<Route path="/cart" element={<div>cart</div>} />
</Routes>
</div>
);
}
const Product = ({ data, onClick }) => {
return (
<Card
className="babo"
style={{ width: '18rem' }}
key={data.id}
onClick={onClick}
>
<Card.Img variant="top" src={`${data.src}`} />
<Card.Body>
<Card.Title>{data.title}</Card.Title>
<Card.Text>{data.content}</Card.Text>
<Card.Text>{data.price}</Card.Text>
<Button variant="primary">Buy</Button>
</Card.Body>
</Card>
);
};
export default App;
useNavigate써주고 인수 넘겨줬음
map에 돌린 Product태그에 onclick이 안되서
onClick통째로 넘겨주고 Product컴포넌트에서 Card에다가 onClick이벤트 달아줬음
# navigate사용
navigate('/detail')
이 함수가 라우터 바꿔주는거. 당연 뒤로가기앞으로가기 편해짐
navigate(-1)
뒤로 이동
앞으로는 1넣어주면 되고..
<Route
path="/detail"
element={
<Detail index={mode.nowIndex} data={shoes} navigate={navigate} />
}
/>
이렇게 Detail component에다가 navigate넣어주고
<button
className="btn btn-danger"
onClick={() => {
navigate(-1);
}}
>
뒤로가기
</button>
Detail component에 onClick버튼으로 뒤로가기 버튼 만들어줌.
동작함
# 404페이지 만들기
<Route path="*" element={<div>404</div>}></Route>
모든 경로 *을 저 element보이게
# nested route
import { Routes, Route, Link, useNavigate, Outlet } from 'react-router-dom';
이렇게 Outlet을 임포트함
<Route path="/about" element={<About></About>}>
<Route path="location" element={<Location />}></Route>
<Route path="history" element={<History />}></Route>
</Route>
/about으로가면 About컴포넌트,
/about/location으로 가면 Location컴포넌트
/about/history로 가면 History컴포넌트 보여주게함
const About = () => {
return (
<div>
<h4>info</h4>
<Outlet></Outlet>
</div>
);
};
const History = () => {
return (
<div>
<h4>history</h4>
</div>
);
};
const Location = () => {
return (
<div>
<h4>location</h4>
</div>
);
};
컴포넌트는 이렇게 만들어주고
About컴포넌트에 Outlet태그를 넣어줘야 /location이냐 /history냐에 따라서 보여주는 컴포넌트가 달라짐.
# 파라미터 사용하기
<h1>아래건 파라미터로</h1>
<div className="img-box">
{shoes.map((data, index) => {
return (
<Product
key={index}
data={data}
onClick={() => {
changeParams(index);
}}
></Product>
);
})}
</div>
메인페이지에서 파라미터로 가는 태그를 따로 만들어줬다.
아래껄 누르면 파라미터로 링크이동하게 해줄거다.
onClick에 파라미터 이동 함수를 달아줬는데,
const changeParams = (i) => {
navigate(`/detail/${i}`);
};
걍 대충 navigate함수로 썼음
그럼 Detail.js에서
import { useParams } from 'react-router-dom';
const Detail = ({ index, data, navigate, onClick }) => {
let { id } = useParams();
if (id) {
index = id;
}
return (
<div className="container">
<div className="row">
<div className="col-md-6">
<img src={data[index].src} width="100%" />
</div>
<div className="col-md-6">
<h4 className="pt-5">{data[index].title}</h4>
<p>{data[index].content}</p>
<p>{data[index].price}</p>
<button
className="btn btn-danger"
onClick={() => {
navigate(-1);
}}
>
뒤로가기
</button>
</div>
</div>
</div>
);
};
export default Detail;
useParams를 사용한다고 임포트해주고
만약 파라미터가 달려있으면 index를 파라미터로 해주고,
없으면 그냥 인수로 받은 index를 쓰라고했다.
그럼 동작한다.
http://127.0.0.1:3000/detail/gadgf
이렇게 파라미터 ㅄ같으면 에러띄워주더라.
404를 안띄워줌. 뭐 고치려면 고칠수있을텐데 귀찮음..
if문 쓰면될듯.
# 파라미터 확장
/detail/:id/dsdsd/:number이런식으로 하면됨.
# 숙제
//bootstrap
import Button from 'react-bootstrap/Button';
import Container from 'react-bootstrap/Container';
import Nav from 'react-bootstrap/Nav';
import Navbar from 'react-bootstrap/Navbar';
import Card from 'react-bootstrap/Card';
//data
import bg from './img/bg.png';
import products from './products.js';
//native react
import { useState } from 'react';
import './App.css';
//library
import { Routes, Route, Link, useNavigate, Outlet } from 'react-router-dom';
//component
import Detail from './Detail.js';
function App() {
const navigate = useNavigate();
const [shoes, setShoes] = useState(products);
const [mode, setMode] = useState({
nowIndex: 0,
});
const changeIndex = (i) => {
const copy = { ...mode };
copy.nowIndex = i;
setMode(copy);
navigate('/detail');
};
const changeParams = (i) => {
navigate(`/detail/${i}`);
};
const arrange = () => {
const copy = [...shoes];
const sortedProducts = copy.slice().sort((a, b) => {
if (a.title < b.title) return -1;
if (a.title > b.title) return 1;
return 0;
});
setShoes(sortedProducts);
};
return (
<div className="App">
<Navbar bg="light" data-bs-theme="light">
<Container>
<Navbar.Brand href="/">Muzzi</Navbar.Brand>
<Nav className="me-auto">
<Nav.Link href="/">Home</Nav.Link>
<Nav.Link href="detail">Detail</Nav.Link>
<Nav.Link href="cart">Cart</Nav.Link>
</Nav>
</Container>
<button className="btn btn-primary" onClick={arrange}>
Sort
</button>
</Navbar>
{/* 링크 */}
<Link to="/">home</Link>
<Link to="/detail">상세</Link>
<Routes>
<Route
path="/"
element={
<div>
<div
className="main-bg"
style={{ backgroundImage: `url('${bg}')` }}
></div>
<div className="img-box">
{shoes.map((data, index) => {
return (
<Product
key={index}
data={data}
onClick={() => {
changeIndex(index);
}}
></Product>
);
})}
</div>
<h1>아래건 파라미터로</h1>
<div className="img-box">
{shoes.map((data, index) => {
return (
<Product
key={index}
data={data}
onClick={() => {
changeParams(index);
}}
></Product>
);
})}
</div>
</div>
}
/>
<Route
path="/detail"
element={
<Detail index={mode.nowIndex} data={shoes} navigate={navigate} />
}
/>
<Route path="/cart" element={<div>cart</div>} />
<Route path="*" element={<div>404</div>}></Route>
<Route
path="/detail/:id"
element={
<Detail index={mode.nowIndex} data={shoes} navigate={navigate} />
}
/>
<Route path="/cart" element={<div>cart</div>} />
<Route path="*" element={<div>404</div>}></Route>
<Route path="/about" element={<About></About>}>
<Route path="location" element={<Location />}></Route>
<Route path="history" element={<History />}></Route>
</Route>
<Route path="/event" element={<Event />}>
<Route path="one" element={<One />}></Route>
<Route path="two" element={<Two />}></Route>
</Route>
</Routes>
</div>
);
}
const Product = ({ data, onClick }) => {
return (
<Card
className="babo"
style={{ width: '18rem' }}
key={data.id}
onClick={onClick}
>
<Card.Img variant="top" src={`${data.src}`} />
<Card.Body>
<Card.Title>{data.title}</Card.Title>
<Card.Text>{data.content}</Card.Text>
<Card.Text>{data.price}</Card.Text>
<Button variant="primary">Buy</Button>
</Card.Body>
</Card>
);
};
const About = () => {
return (
<div>
<h4>info</h4>
<Outlet></Outlet>
</div>
);
};
const History = () => {
return (
<div>
<h4>history</h4>
</div>
);
};
const Location = () => {
return (
<div>
<h4>location</h4>
</div>
);
};
const Event = () => {
return (
<div>
<h4>오늘의 이벤트</h4>
<Outlet></Outlet>
</div>
);
};
const One = () => {
return (
<div>
<p>첫 주문시 양배추즙 서비스</p>
<Outlet></Outlet>
</div>
);
};
const Two = () => {
return (
<div>
<p>생일기념 쿠폰받기</p>
<Outlet></Outlet>
</div>
);
};
export default App;
'javaScript > react' 카테고리의 다른 글
데이터 모듈화 (0) | 2024.07.30 |
---|---|
이미지 파일 관리 + public파일 경로 (0) | 2024.07.30 |
bootstrap 연동하기 (0) | 2024.07.29 |
onChange 이벤트(+이벤트 버블링 막기) (0) | 2024.07.23 |
looooooooooop (0) | 2024.07.18 |