React 라우터 URL 파라미터로 상세페이지 100개 만들기

재웅·2023년 4월 24일
0

오늘의 정리

목록 보기
30/52
post-thumbnail

상세페이지 여러개 만들려면

일단 Route 쓰면 페이지 하나 만들 수 있다고 했으니까...

<Route path="/detail/0" element={ <Detail shoes={shoes}/> }/>
<Route path="/detail/1" element={ <Detail shoes={shoes}/> }/>
<Route path="/detail/2" element={ <Detail shoes={shoes}/> }/> 
.
.

뭐 요딴 식으로 페이지 계속 만들수야 있겠지만 1000개 넘으면 어뜩할래?

너무 끔찍하니 다른 방법을 사용해보자

<Route path="/detail/:id" element={ <Detail shoes={shoes}/> }/>

페이지 여러개 만들고 싶으면 URL 파라미터 문법 사용하면 되는데

path 작명할때 /:어쩌구 이렇게 하면 "아무 문자" 를 뜻함

그래서 위 Route는 주소창에 /detail/아무문자 입력했을 때 Detail 컴포넌트를 보여달라는 뜻임

이제 그럼 /detail/0 , /detail/1 , /detail/2 접속해도 Detail 컴포넌트 잘 보여줌


페이지마다 똑같은 내용은 보여주기 싫은데요

(Detail.js)

<h4 className="pt-5">{props.shoes[현재url에입력된숫자].title}</h4>
<p>{props.shoes[0].content}</p>
<p>{props.shoes[0].price}</p>
<button className="btn btn-danger">주문하기</button>

뭐 이런식으로 짜면 될것같은데요

저런 숫자 어케 가져옴?

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() 라는 함수를 상단에서 import 해오면 쓸 수 있는데

이거 쓰면 현재 /:url파라미터 자리에 유저가 입력한 값 가져올 수 있음

변수에 저장해서 쓰던가 하면 될듯

그래서 위처럼 사용하면

/detail/1 로 접속하면 id라는 변수에 1이 들어오고

/detail/2 로 접속하면 id라는 변수에 2가 들어옴

그럼 원하는대로 기능 완성 되겠네용

(참고)

path 작명시 url 파라미터는 몇번이고 사용 가능. detail/:어쩌구/:저쩌구 이런식으로


살짝 응용문제

Q.자료의 순서가 변경되면 상세페이지도 고장나는 문제는 어떻게 해결함

상품 순서를 가나다순으로 변경하는 버튼을 만들었다고 가정하고

그거 누르면 shoes라는 state 안의 상품이 정렬됨

그럼 다른 상품이 0번 상품이 되어버리는거임

평소엔 /detail/0 으로 접속하면 0번째 상품을 보여주니까 기존의것이 뜰텐데

버튼 누른후엔 /detail/0으로 접속하면 바뀐 0번째 상품때문에 바뀌어버림;

이거 어떻게 해결해야 합니까요

Hint : 상품의 영구번호가 0인 상품의 제목을 보여주세요~ 라고 하면 될듯
영구번호는 shoes라는 상품 데이터안에 {id:0} 요런식으로 저장되어있음
그래서 현재 url에 입력한 번호와 같은 번호를 가진 상품을 찾아서 데이터 바인딩해달라고 하면 끝일듯

//이건 상품 데이터 
(data.js)
[
  {
    id : 0,  //여기 영구번호 있잖슴
    title : "White and Black",
    content : "Born in France",
    price : 120000
  },
  {둘째상품},
  {셋째상품}
] 

js엔 .find()라는 문법 있는데 이거 쓰면 array 자료안에서 원하는 항목만 찾아올 수 있음

array자료.find( () => { 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>{찾은상품.content}</p>
          <p>{찾은상품.price}</p>
          <button className="btn btn-danger">주문하기</button> 
        </div>
      </div>
  </div>  
  )
};

export default Detail 
profile
오늘의 정리

0개의 댓글