url 파라미터를 사용해보자

gotcha!!·2023년 11월 5일
0

React

목록 보기
6/15

쇼핑몰 사이트를 만들 때, 제품의 상세페이지를 볼 수 있는 페이지가 있을 것이다.

서론

<Route path="/detail" element= {<Detail item = {item}/>}/>

나 같은 경우에 App.js 안에 item이라는 데이터를 state로 보관중에 있다.
그리고 라우터를 하나 만들어 Detail 을 쓰는 곳에 item 이라는 데이터를 프롭스 전송시켰다.

Deatil.js

const DetailPage = function detailComponent(props){
  
  return(
      <div className="container">
          <div className="row">
              <div className="col-md-6">
                  <img src={`https://codingapple1.github.io/shop/shoes${findItem.id + 1}.jpg`} width="100%" />
              </div>
              <div className="col-md-6">
                  <h4 className="pt-5">{props.item[0].title}</h4>
                  <p>{props.item[0].content}</p>
                  <p>{props.item[0].price}원</p>
                  <button className="btn btn-danger">주문하기</button> 
              </div>
          </div>
      </div>
  )
}

이렇게 props를 전달해서 상세페이지에서 props.item[0].정보들을 출력할 수 있었다.

여기서 한가지 의문점
Q. 그냥 Detail.js에서 item이라는 state를 보관하면 되지 않나?
A. 그러면 나중에 수정이 필요하면 Detail.js와 App.js에서 state를 수정해야하기에 귀찮아지므로 데이터를 받아오는 것은 한군데서만 하자.

상세 페이지가 많으면요?

만약 데이터가 3개있다고 생각을 해보고 상세 페이지를 만들면

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

이렇게 만들어도 크게 문제가 없다.
근데 데이터는 당연히 3개가 아닐거고 무수히 많이 존재할 것이다.

그래서 url파라미터 문법을 사용해보자

페이지를 여러개 만들고 싶다?
그러면 url 파라미터 문법을 사용하면 된다.

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

위와 같이 path에서 "/url/:뭐시기 라고 사용하면 /detail/뭐시기 라 입력했을 때 그에 맞는 컴포넌트를 보여줄 수 있다.

내가 앞서 쓴 코드를 수정해보자

앞서 사용했던 코드에는 상세페이지에 item이라는 데이터를 보여주는데 항상 0번째 데이터를 보여준다.
내가 원하는 아이템의 상세 페이지를 보여주려면 어떻게 해야할까?

간단하다

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.item[id].title}</h4>
        <p>{props.item[id].content}</p>
        <p>{props.item[id].price}원</p>
        <button className="btn btn-danger">주문하기</button>
      </div>
    </div>
  </div>
  )
}
                                          

useParams()라는 함수를 상단에서 import해서 변수에 저장해두고 그 값을 사용하면된다.

여기서도 한 가지 문제점

만약 메인페이지에서 상품의 순서를 정렬해버리고 상품 디테일 페이지로 오게되면 B라는 상품을 클릭했는데, A라는 상품 페이지로 이동되거나 그럴 수 있다.
그럴 때 어떻게 해결해야할까.

find() 메서드를 사용해보자

내가 App.js에서 저장한 state에는 고유한 id값을 가지고 있다.

let data = [
   {
     id : 0,
     title : "컨버스 신발",
     content : "Born in France",
     price : 120000
   },
 
   {
     id : 1,
     title : "아식스 신발",
     content : "Born in Seoul",
     price : 110000
   },
 
   {
     id : 2,
     title : "조던 신발",
     content : "Born in the States",
     price : 130000
   }
 ] 

이렇게 말이다.

그럼 url파라미터에 입력한 값과 data의 고유한 id 값과 같은지 체크해보고 같으면 해당 상품을 보여주면 되지 않을까?

const DetailPage = function detailComponent(props){
    let {id} = useParams();
    let findItem = props.shoes.find( (shoes) =>{
        return shoes.id == id; 
    })
    
    return(
        <div className="container">
            <div className="row">
                <div className="col-md-6">
                    <img src={`https://codingapple1.github.io/shop/shoes${findItem.id + 1}.jpg`} width="100%" />
                </div>
                <div className="col-md-6">
                    <h4 className="pt-5">{findItem.title}</h4>
                    <p>{findItem.content}</p>
                    <p>{findItem.price}원</p>
                    <button className="btn btn-danger">주문하기</button> 
                </div>
            </div>
        </div>
    )
}

그래서 find() 메서드를 통해서 shoes 속에 id와 url 파라미터로 넘어온 id와 같은지를 체크하고 같으면 그 id에 맞는 값을 리턴하였다.
그리고 리턴한 값으로 출력하면 끝!

profile
ha lee :)

0개의 댓글