이와같은 창에서 각 상품별로 상세페이지를 이동할때 라우팅을 사용하면 매우좋다.
부드럽게 작동하기도하고 별도의 페이지를 만들기보다 컴포넌트 형태로 이동할 수 있다.
리액트 라우터를 사용하려면 설치부터해야한다!
npm install react-router-dom@5
yarn add react-router-dom@5
둘중 하나 사용해주면된다, 구글 검색하면서 세팅하도록하자
그리고 index.js에서 아래와같이 세팅해줘야함
import { BrowserRouter } from 'react-router-dom'
// 이거 하나를 불러와 줘야한다. /같은 경로없이 불러오는건 라이브러리다.
// import { HashRouter } from 'react-router-dom'
// 이와같이해도된다. 이건 주소에 #기호가 붙는다. 똑같지만 차이는 라우팅을 안전하게 할 수 있게도와준다.
// #이붙는거는 서버로 전달하지않는다 #은 서버에서 설정이 필요할 수 있다.
이와같이 BrowserRouter를 불러오는걸 알고있자, 해쉬 라우터를 불러와도되지만 조금의 차이가 있다.
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
{/* 이렇게 감싸주면 설정은 끝이다. */}
</React.StrictMode>,
document.getElementById('root')
);
그리고 이와같이 기존의 <App/>컴포넌트를 감싸주면 작동시킬 수 있다.
import {Link, Route, Switch} from 'react-router-dom'
그리고 app.js에서 이와같이 3개를 import해올건데 각각 기능을 알아보자
우선 원하는곳에 라우팅하려면
<Route></Route>
이와같이 불러와서 사용하면된다. 그리고 이안에 path를 적어주면된다
<Route path="/"></Route>
<Route path="/detail"></Route>
<Route path="/작명" component={Card} ></Route>
<Route path="/작명"> <Card/> </Route>
그리고 이렇게 다 작성이가능함 안에 컴포넌트를 넣을 수 있다.
이런식으로하면 컴포넌트를 다른페이지를 보여주는것처럼 나타낼 수 있다. 작동도 부드럽게된다.
그리고 이런식으로 만들면 /가 포함된 모든페이지가 다 보이게 되는데 이런경우는
exact를 사용해주면된다.
<Route exact path="/">
</Route>
이와같이하면 / 가 있는 페이지만 보여준다.
Link,Switch,history
참고로 이전에 데이터를 import,export한것처럼 컴포넌트도 import,export해올 수 있다.
import React,{useState} from 'react';
import { useHistory,useParams } from 'react-router-dom/cjs/react-router-dom.min';
// 컴포넌트 만들때 꼭 import해오기
function Detail(props){
let{ id } = useParams();
// 파라미터값 변수로 저장해서 쓸 수 있다. 여러개가있으면 id,id2,id3..이런식으로 넣어주면댐
let history = useHistory();
// react-router-dom 여기들어있다. 훅입니다.
// 방문기록등을 저장해놓는 object
//이곳에다가 shoes데이터 Usetate해서 넣어도되지만 app에 넣는게 정석이다.
//상위->하위컴포넌트로 쓰는게 정석 반대는 어렵기 때문
let 찾은상품 = props.shoes.find(function(상품){
return 상품.id==id
})
// return오른쪽엔 조건식이가능 이게 참이면 상품 즉 array의 하나가 찾은상품 값으로 들어감
return(
<div className="container">
<div className="row">
<div className="col-md-6">
<img src={"https://codingapple1.github.io/shop/shoes"+(찾은상품.id+1)+".jpg"} width="100%" />
</div>
<div className="col-md-6 mt-4">
<h4 className="pt-5">{찾은상품.title}</h4>
<p>{찾은상품.content}</p>
<p>{찾은상품.price}</p>
{/* <h4 className="pt-5">{props.shoes[id].title}</h4>
<p>{props.shoes[id].content}</p>
<p>{props.shoes[id].price}</p> */}
<button className="btn btn-danger">주문하기</button>
<button className="btn btn-danger" onClick={()=>{
// history.goBack() // 뒤로 이동시키기
history.push('/')//특정 경로로 이동시키기
// 이런건 검색해서 사용하면된다.
}}>뒤로가기</button>
</div>
</div>
</div>
)
}
export default Detail;
// 변수명 or 함수명 적어주기
이와같이 컴포넌트 전체를 넣어주고 import react와 맨아래 export해주면 컴포넌트역시 다른 파일로 넣을 수 있다.
import Detail from './Detail.js'
...
<Detail></Detail>
이렇게 불러와 바로 컴포넌트처럼 사용 할 수 있다. 마찬가지로 props까지 전부 사용가능하다.
- Link
Link to 를 이용해 경로를 이동할 수 있게 만들어줄 수 있다.
<Navbar bg="light" variant="light">
<Container>
<Navbar.Brand href="#home">SHOP</Navbar.Brand>
<Nav className="me-auto">
{/* 라우터 라이브러리문법, 링크 Link불러왔음 <Link to="/">Home</Link>*/}
<Nav.Link ><Link to="/">Home</Link></Nav.Link>
<Nav.Link ><Link to="/detail">Detail</Link></Nav.Link>
<Nav.Link href="#pricing">Pricing</Nav.Link>
</Nav>
</Container>
</Navbar>
Navbar 안에 a태그 링크부분을 Link to 로 바꾼모습이다.
이것과 별개로 뒤로가기느 특정페이지에서 특정페이지로 이동하게 하려면
useHistory를 사용할 수 있다.
<Nav.Link as={Link} to="/"> Home </Nav.Link>
참고로 이런식으로바꿔주면 오류없이 사용할 수 있다.
-history
import React,{useState} from 'react';
import { useHistory,useParams } from 'react-router-dom/cjs/react-router-dom.min';
// 컴포넌트 만들때 꼭 import해오기
function Detail(props){
let{ id } = useParams();
let history = useHistory();
let 찾은상품 = props.shoes.find(function(상품){
return 상품.id==id
})
return(
<div className="container">
<div className="row">
<div className="col-md-6">
<img src={"https://codingapple1.github.io/shop/shoes"+(찾은상품.id+1)+".jpg"} width="100%" />
</div>
<div className="col-md-6 mt-4">
<h4 className="pt-5">{찾은상품.title}</h4>
<p>{찾은상품.content}</p>
<p>{찾은상품.price}</p>
{/* <h4 className="pt-5">{props.shoes[id].title}</h4>
<p>{props.shoes[id].content}</p>
<p>{props.shoes[id].price}</p> */}
<button className="btn btn-danger">주문하기</button>
<button className="btn btn-danger" onClick={()=>{
// history.goBack() // 뒤로 이동시키기
history.push('/')//특정 경로로 이동시키기
// 이런건 검색해서 사용하면된다.
}}>뒤로가기</button>
</div>
</div>
</div>
)
}
export default Detail;
// 변수명 or 함수명 적어주기
이와같은 코드에서
<button className="btn btn-danger" onClick={()=>{
// history.goBack() // 뒤로 이동시키기
history.push('/')//특정 경로로 이동시키기
// 이런건 검색해서 사용하면된다.
}}>뒤로가기</button>
이렇게 사용할 수 있다.
history.goBack()을 사용하면 단순히 뒤로가게되고, push를 사용하면 특정경로를 지정해서 이동 시킬 수 있다.
이것도 Hook이고, useState처럼 중간에 변수로 useHistory()를 불러와 사용한다.
-Switch
<Route path="/:id">
여기를보여준다.
</Route>
exact를 쓰지않고 해결하는 방식이다. 위와같이하면
/다음에 아무문자,숫자가와도 저 페이지를 보여준다.
<Switch>
<Route path="/">
</Route>
<Route path="/detail">
</Route>
<Route path="/:id">
</Route>
</Switch>
이런식으로 라우트를 감싸주면 매칭되는 맨위의것 하나만 보여줄 수 있다.
이렇게 안하면 밑에 /:id 는 /다음 모든 문자가오면 다 나오게 된다.
데이터바인딩
import,export해온곳에도 마찬가지로 props로 데이터를 전송 할 수 있다.
<Detail shoes={shoes}></Detail>
이와같이 Detail.js에서 불러온 컴포넌트에도 props형식을 지켜주고
Detail.js안에서 props로 데이터를 사용할 수 있다.
그리고 항상 상위컴포넌트에서 하위컴포넌트로 자료를 보내는게 좋기때문에
하위컴포넌트에서 data를 만들 수 는 있지만 사용하지 않는게 좋다.
URL 파라미터 문법
<Route path="/detail/:id">
<Detail shoes={shoes}></Detail>
{/* 이것도 props는 마찬가지로 쓸 수 있다. */}
</Route>
이와같이 Route안에 Detail 컴포넌트를 넣었는데 :id부분을 변수처럼 URL파라미터로 가져올 수 있다.
id는 다른명칭으로 바꿔도 된다. 갯수는상관없다. /detail/:id/:name 같은 형태도 가능함
import React,{useState} from 'react';
import { useHistory,useParams } from 'react-router-dom/cjs/react-router-dom.min';
// 컴포넌트 만들때 꼭 import해오기
function Detail(props){
let{ id } = useParams();
// 파라미터값 변수로 저장해서 쓸 수 있다. 여러개가있으면 id,id2,id3..이런식으로 넣어주면댐
let history = useHistory();
// react-router-dom 여기들어있다. 훅입니다.
// 방문기록등을 저장해놓는 object
//이곳에다가 shoes데이터 Usetate해서 넣어도되지만 app에 넣는게 정석이다.
//상위->하위컴포넌트로 쓰는게 정석 반대는 어렵기 때문
let 찾은상품 = props.shoes.find(function(상품){
return 상품.id==id
})
// return오른쪽엔 조건식이가능 이게 참이면 상품 즉 array의 하나가 찾은상품 값으로 들어감
return(
<div className="container">
<div className="row">
<div className="col-md-6">
<img src={"https://codingapple1.github.io/shop/shoes"+(찾은상품.id+1)+".jpg"} width="100%" />
</div>
<div className="col-md-6 mt-4">
<h4 className="pt-5">{찾은상품.title}</h4>
<p>{찾은상품.content}</p>
<p>{찾은상품.price}</p>
{/* <h4 className="pt-5">{props.shoes[id].title}</h4>
<p>{props.shoes[id].content}</p>
<p>{props.shoes[id].price}</p> */}
<button className="btn btn-danger">주문하기</button>
<button className="btn btn-danger" onClick={()=>{
// history.goBack() // 뒤로 이동시키기
history.push('/')//특정 경로로 이동시키기
// 이런건 검색해서 사용하면된다.
}}>뒤로가기</button>
</div>
</div>
</div>
)
}
export default Detail;
// 변수명 or 함수명 적어주기
이와같이 상단에 param을 불러와 사용해주면된다.
<h4 className="pt-5">{props.shoes[id].title}</h4>
<p>{props.shoes[id].content}</p>
<p>{props.shoes[id].price}</p>
이와같이 props로 가져와 id값에 param변수를 넣어도 사용하면 되지만 이렇게사용하면
추후 정렬된상태에서는 그저 순서대로만 가져오는 문제가 발생한다. 이러한경우는
자료의 id값을 활용한다.
export default [
{
id : 0,
title : "White and Black",
content : "Born in France",
price : 120000
},
{
id : 1,
title : "Red Knit",
content : "Born in Seoul",
price : 110000
},
{
id : 2,
title : "Grey Yordan",
content : "Born in the States",
price : 130000
}
]
이렇게 되어있는자료안에 id값을 활용하면 순서가 바뀌어도
param값과 일치하는 id의 자료를 가져오면된다.
let 찾은상품 = props.shoes.find(function(상품){
return 상품.id==id
})
find함수를 사용해도되지만 map이나 filter등 다른걸 사용해도 상관없다.
중요한건 같은 id값을, param값과 일치하는 값을 찾아 나타내면 되는거다.
'React' 카테고리의 다른 글
React useEffect (0) | 2022.01.15 |
---|---|
React Style(CSS,SASS) (0) | 2022.01.14 |
React 컴포넌트화(Component) 해서 반복문이용, 이미지도 순서반복 (0) | 2022.01.12 |
React import,export 활용하기 (코드 쪼개기) (0) | 2022.01.12 |
React Bootstrap 응용 (0) | 2022.01.12 |