React - 리액트라우터3 : URL 파라미터로 상세페이지 100개 만들기😮

신혜원·2023년 7월 4일
0

React

목록 보기
21/37
post-thumbnail

🖤 상세페이지에 상품명 넣어보기

  • shoes라는 state에 있던 상품정보들로 내용 채울 예정이다.
  • shoes 는 App 컴포넌트에 있으니 App -> Detail 로 전송하면 쓸 수 있다. (props 사용하면 된다!!)
(App.js)
<Route path="/detail" element={ <Detail shoes={shoes}/> }/> 
  • App.js 안에 <Detail>을 쓰는 곳에서 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 : 0번째 상품명이 나온다.

🤍 shoes 라는 state를 Detail.js 안에서 다시 만들면 굳이 props가 필요가 없지 않은가 ??

  • 그렇게 되면 나중에 수정 할 때 두 군데를 수정해야 하므로 지양하는 것이 좋다.

🖤 상세페이지 여러 개 만들기

  • 상품이 3개이므로 상세페이지도 3개가 필요하다.
  • <Route>를 쓰면 페이지 하나를 만들 수 있다고 했으니 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}/> }/> 
  • 하지만 이렇게 하나하나 쓴다면 만약 상품이 100개일 경우에는 <Route> 를 100개 만들어야 하므로 다른 방법을 사용해야 한다.
  • 다른사이트를 벤치마킹 하는 것도 좋은 방법!
<Route path="/detail/:id" element={ <Detail shoes={shoes}/> }/>
  • 페이지를 여러 개 만들 때 사용하는 URL 파라미터 문법을 알아보자.
  • Route path를 작명 할 때 "/:어쩌구" 이렇게 사용하면 "아무 문자" 를 뜻하게 된다.
  • 위 코드는 누군가 주소창에 /detail/아무거나 를 입력했을 때 <Detail> 컴포넌트를 보여달라는 뜻이다.
    ex) /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>
  • 0 이라고 하드코딩 했던 자리에 현재 url파라미터에 입력된 숫자를 넣으면 된다.
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[id].content}</p>
        <p>{props.shoes[id].price}원</p>
        <button className="btn btn-danger">주문하기</button>
      </div>
    </div>
  </div>
  )
}
  • useParams() 라는 함수를 import 해오면 "/:url파라미터" 자리에 유저가 입력한 값을 가져올 수 있다.

🤍 이미지 src 도 파라미터로 바꿔주기

  • 강의에서 이미지는 바꾸지 않았기 때문에 지난시간에 배웠던 것을 이용해 이미지도 각각의 상품에 맞게 변경하도록 수정했다.
<img src={"https://codingapple1.github.io/shop/shoes" + props.i + ".jpg"} />

📒 오늘의 숙제

  • 만약 상품 순서를 가나다순으로 변경하는 버튼을 만들었다고 가정한다.
  • 버튼을 누르면 shoes라는 state 안의 상품이 가나다 순으로 정렬이 된다.
  • 오늘 배운 내용대로라면 /detail/0 이 0번째 상품을 보여주기 때문에 White and Black 이 떠야하지만 정렬버튼을 누른 후 /detail/0 으로 접속하면 Grey Yordan 이 뜨게된다.
  • 상세페이지가 불규칙해지는 문제를 해결해보자.

  • (힌트) 상세페이지가 불규칙해지는 문제를 해결하려면 상품의 영구번호를 보여주는 식으로 하면 된다. ex) shoes 상품 속 {id:0}
  • 현재 url에 입력한 번호와 같은 번호를 가진 상품을 찾아서 데이터바인딩 해달라고 코드를 짜면 된다.

🚨 주어진 시간은 1시간

let result = props.shoes.find((result) => props.shoes.id === "0");
  console.log(result);
  • id : 0 인 object 를 꺼내려고 했지만 잘 되지 않는다..
let result = props.shoes.find((result) => result.id === 0);
  console.log(result);

  • id 가 0인 object가 잘 나타났다.

💡 Arrow Function (화살표 함수)에 대해 먼저 이해하고 넘어가야한다.
ex) function(){ return ~~ } 👉 () => { return ~~ };

"function 이 화살표로 변한다." 라고 생각하면 된다.
따라서 처음에 입력한 코드를 보면 result 라는 파라미터를 사용했으므로 return 안에서 props.shoes. 가 아닌 result.id 로 했을 때 작동이 잘 되는 것이다.


💡find() 에 대해 알아보자.

1. 내가 원하는 key의 값을 뽑아내는 함수를 작성한다.
2. 값이 들어있는 배열.find( object의 key의 값을 뽑아내는 함수 ) 를 해준다.
📗출처 : https://www.youtube.com/watch?v=N1QcR8F3xFY

props.shoes.find((result) => result.id === 0);
  • 즉 이 코드는 아래와 같은 코드이다.
function Findid(result) {
  return result.id === 0;
}
props.shoes.find(Findid);
function Detail(props) {
  let { id } = useParams();
  console.log(id);
  let result = props.shoes.find((result) => result.id === id);
}
  • 배열에서 id가 0인 object 를 뽑아낸 상황에서는 작동이 잘 되었지만 url 파라미터와 비교했을 때 undefined가 뜨는 상황이 자꾸 반복되었다.
  • 도움을 받고자 해설을 살짝 봤는데 비교연산자만 달랐다😅😅
function Detail(props) {
  let { id } = useParams();
  let result = props.shoes.find((result) => result.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">
            <h4 className="pt-5">{result.title}</h4>
            <p>{result.content}</p>
            <p>{result.price}원</p>
            <button className="btn btn-danger">주문하기</button>
          </div>
        </div>
      </div>
    </>
  );
}

✍ 비교연산자만의 문제이고 다른 해설 부분은 내가 혼자 찾아가면서 적은 부분들이라 꽤 보람이 있었다😁😁

0개의 댓글