리액트 URL 파라미터 정리 (useParams 사용하기)

버건디·2022년 8월 18일
0

리액트

목록 보기
16/58
post-thumbnail

만약에 Detail 이라는 페이지를 만들고 또 그에 따른 상세페이지들( Detail/0, Detail/1 Detail/2 .. )을 만든다고 가정해보자.


//App.js 

import Detail from "./routes/Detail";

let [product] = useState(data);

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

// Detail 컴포넌트

function Detail(props) {
  return (
    <div className="container">
      <div className="row">
        <div className="col-md-6">
          <img
            src="picture4.jpeg"
            width="50%"
          />
        </div>
        <div className="col-md-6">
          <h4 className="pt-5">{props.product[0].title}</h4>
          <p>{props.product[0].content}</p>
          <p>{props.product[0].price}</p>
          <button className="btn btn-danger">주문하기</button>
        </div>
      </div>
    </div>
  );
}

export default Detail;

이런식으로 코드를 짜면, 나중에 상세페이지들의 개수가 많아질때 문제가 생긴다.

❗️ URL 파라미터 문법은 페이지의 주소를 정의할때, 유동적인 값을 전달하기 위한 문법이다 ❗️


🔍 URL 파라미터 구현하기

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

위의 코드가 의미하는 바는 사용자가 /Detail/아무거나 를 입력했을때, 저 Detail 컴포넌트를 보여달라는 의미이다.

실제로 뒤에 아무 의미없는 글자를 넣었는데도 Detail 컴포넌트 페이지가 나온다.

하지만 여기서 문제가 발생하는데, 다른 상세페이지를 접속하기 위해서 다른 글자들을 입력해도 결국엔
똑같은 페이지만 보여준다는 것이다. 코드안에서 index 0 에 해당하는 내용을 바인딩 해놔서 그렇다.

❗️ 한 컴포넌트에서 각각의 내용을 보여주고 싶을때 사용하는 것이 useParams 라는 Hook이다 ❗️

🔍 useParams 사용하기

1. 컴포넌트 내에서 useParams() 호출하기

import { useParams } from "react-router-dom";

let {id} = useParams();

이렇게 저 id 값이 사이트에 접속한사람이 입력한 값으로 들어가게된다. 확인을 위해서 console.log(id)를 해보면

주소창에 입력한 id 값이 콘솔창에 그대로 나오는것을 볼 수 있다.

<div className="col-md-6">
          <h4 className="pt-5">{props.product[id].title}</h4>
          <p>{props.product[id].content}</p>
          <p>{props.product[id].price}</p>
          <button className="btn btn-danger">주문하기</button>
</div>

즉 Detail/0 을 입력하면 0번째 상품을, Detail/1 을 입력하면 1번째 상품을 보여줄수 있도록 한것이다.


만약에 제품 정렬 버튼을 하나 만들어 놓고 정렬이 된 후에 Detail/0을 접속하면 원래의 0번째 제품이 아니라, 정렬이 된 후의 0번째 제품이 나오는데 상품의 영구번호대로 바인딩하려면 어떻게 해야할까?

let data = [
    {
      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
    }
  ];

  export default data;

위에 코드가 가지고 있는 데이터고 각 데이터들은 id 라는 Key를 가지고 있다.

이 id와 사용자가 입력한 id가 같은 제품을 보여주고 싶은거니까

let {id} = useParams();
let Product = props.product.find((x) => x.id == id );

<div className="col-md-6">
          <h4 className="pt-5">{Product.title}</h4>
          <p>{Product.content}</p>
          <p>{Product.price}</p>
          <button className="btn btn-danger">주문하기</button>
        </div>

find 메서드를 사용하여 제품들의 id 값 == 사용자가 입력한 id가 같은 제품을 보여주도록 하면 된다.

profile
https://brgndy.me/ 로 옮기는 중입니다 :)

0개의 댓글