특정 component에 urlParams를 사용한 데이터 바인딩으로 동적인 페이지 구현하려고 함
props를 써서 할 수 있겠지만 리엑트 라우터적으로 구현할거임!
(App.js)
<Route path="/detail" element={ <Detail shoes={shoes}/> }/>
우선 app.js안에 <Detail>component를 사용하는곳에 shoes라는 props를 전송했다.
(Detail.js)
<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 mt-4">
<h4 className="pt-5">{props.shoes[0].title}</h4>
<p>{props.shoes[0].content}</p>
<p>{props.shoes[0].price}원</p>
<button className="btn btn-danger">주문하기</button>
</div>
</div>
</div>
Detail 컴포넌트는 props파라미터를 등록해서 shoes를 사용했음.
근데 props.shoes[0].title을 하면 어떤 주소를 이동해도 다 같은 shoes[0] 상품의 디테일페이지가 나옴
shoes state를 Detail.js안에서 또 만들면 props를 안써도 되지 않나?
→ 나중에 수정이 필요하면 두 군데를 수정해야하므로 이런식으로 하면 안됨.
위에서 만든건 shoes state안에 0번째 상품의 상세페이지임.
상품이 3개면 상세페이지도 3개가 필요함.
<Route path="/detail/0" element={ <Detail shoes={shoes}/> }/>
<Route path="/detail/1" element={ <Detail shoes={shoes}/> }/>
<Route path="/detail/2" element={ <Detail shoes={shoes}/> }/>
<Route>를 3개 만들어도 페이지 3개를 만들 수도 있겠지만 데이터가 많으면 많을수록 실제로 사용이 어려운 코드..
<Route path="/detail/:id" element={ <Detail shoes={shoes}/> }/>
그래서 이럴때 쓸 수 있는게 URL 파라미터 문법이다.
path 작명할 때 /:어쩌구~
이렇게 사용하면 "아무문자"를 뜻함.
그래서 위에 <Route>는 누군가 주소창에 /detail/아무거나를 입력했을 때 <Detail>컴포넌트를 보여달라는 뜻.
이제그럼
/detail/0
/detail/1
/detail/2
이렇게 접속해도 <Detail> 컴포넌트를 잘 보여줄 수 있음.
/detail/skfjlsjfl...
이런식으로 막 접속해도 <Detail>페이지가 보인다.
/detail/0
/detail/1
/detail/2
이렇게 여러 페이지를 만들어 놨지만 접속해보면 다 똑같은 0번째 상품만 보여줌.
props.shoes[0]번째를 보여달라고 하드코딩해놨기 때문임.
지금 하드코딩된 자리에 현재 url 파라미터에 입력된 숫자를 넣으면 /detail/1로 접속하면 1번째 상품을 보여줄 수 잇을 듯?
import { useParams } from 'react-router-dom'
function Detail(){
let {id} = useParams();
console.log(id)
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 mt-4">
<h4 className="pt-5">{props.shoes[id].title}</h4>
<p>{props.shoes[0].content}</p>
<p>{props.shoes[0].price}원</p>
<button className="btn btn-danger">주문하기</button>
</div>
</div>
</div>
)
}
useParams()함수를 쓰면 :/url파라미터자리에 유저가 입력한 값을 가져올 수 있음.
우선 useParams()함수를 상담에 import해오고,
변수에 저장해서 쓰겠음.
위 코드처럼 사용하면
누가 /detail/1로 접속하면 id라는 변수에 1이 들어오고,
누가 /detail/2로 접속하면 id라는 변수에 2이 들어온다.
그래서 props.shoes[id].title을 해주면
페이지마다 각각 다른 상품명을 보여줄 수 있음.
📎참고
path작명 시 url파라미터는 몇 번이고 사용 가능함.
detail/:어쩌구/:저쩌구~..
상품순서를 가나다순으로 변경하는 버튼을 만들었다고 가정하면,
이 버튼을 클릭 시 shoes라는 state안에 상품이 가나다순으로 정렬되게 된다.
그럼 원래 0번째 상품이었던 데이터가 후순위로 밀려나게되고, 차순위였던 상품의 데이터가 0번째가 될 수 있는데,
이처럼 상세페이지가 불규칙해지는 문제를 해결해보자!
hint!
Detail.js에 데이터바인딩할 때 0번째 상품의 제목을 보여달라고 코드를 짰는데,
상품의 영구번호가 0인 상품의 제목을 보여달라고 작성하면 될 듯 하다.
그래서 현재 url에 입력한 번화와 같은 번호를 가진 상품을 찾아 데이터 바인딩하면 끝일 듯
.find()
,.find()
같은 문법을 찾아보기
A.
(data.js)
[
{
id : 0,
title : "White and Black",
content : "Born in France",
price : 120000
},
{둘째상품},
{셋째상품}
]
data.js파일에 상품정보 데이터들이 들어있는데, 이 안에 id:0이런 영구번호가 있음.
현재 /:id자리에 입력한 값과 영구번호가 같은 상품을찾아 데이터 바인딩 해주면 해결!
js엔 .find()라는 문법이 있는데 이걸 쓰면 array자료 안에 원하는 항목만 찾아올 수 있다.
array자료.find(()=>{return 조건식});
이런식으로 쓰면 조건식에 맞는 자료를 찾아 return자리에 남겨줌.
(Detail.js)
function Detail(props){
let { id } = useParams();
let 찾은상품 = props.shoes.find(function(x){
return x.id == id
});
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 mt-4">
<h4 className="pt-5">{찾은상품.title}</h4>
<p>{zzz.content}</p>
<p>{찾은상품.price}원</p>
<button className="btn btn-danger">주문하기</button>
</div>
</div>
</div>
)
};
export default Detail;
더 짧게는
props.shoes.fild((x)=>x.id==id);
라우터부분은 반복적으로 더 연습해봐야 할 문제같다.
그리고 자바스크립트가 정말 많이 부족하다고 느낀점은
응용문제가 실제로 많이 쓸법한 기초문제 문제였던것 같은데 나한텐 좀 어려웠다..
function도 finde랑 filter를 찾으면서 알게되었는데
유사한 다른 함수들도 많았다.
지하철에서나 자기전에 읽고자기만 해도 도움이 될 듯 하다! 화이팅!
주제엔 조금 어긋나지만 저번 코테에서 봤던 readline! 자바에 scanner와 비슷한 기능인 듯
hook은 강의에서도 너무간단하게 설명해주시고 넘어가셔서 궁금해짐
리덕스도 공부해보기!