지난 시간에 배운 Route 태그의 path 속성을 이용하여 상세 페이지를 만들어 보았다.
/* App.js */
<Route path='/detail/:id' element={<DetailPage desserts={desserts}/>} />
path는 경로를 나타내고 id는 매개변수로, 여기에는 어떠한 값이든 올 수 있다. 이 매개변수는 DetailPage 컴포넌트에서 사용된다.
element 부분은 해당 경로에 매칭될 때 렌더링될 컴포넌트를 지정한다. 현재는 DetailPage 컴포넌트가 desserts prop을 받아오고 있다.
/* Detail.js */
import React from "react";
import { useParams } from "react-router-dom";
const DetailPage=(props)=> {
let {id} = useParams();
// useParams에서 가져온 id는 문자열 형태이므로 형변환을 해줘야 함
const imageNum = Number(id) + 1;
const imageUrl = `${process.env.PUBLIC_URL}/img/col${imageNum}.jpg`;
return (
<div className="container">
<div className="row">
<div className="col-md-6">
<img src={imageUrl} width="100%" />
</div>
<div className="col-md-6">
<h4 className="pt-5">{props.desserts[id].title}</h4>
<p>{props.desserts[id].content}</p>
<p>{props.desserts[id].price}</p>
<button className="btn btn-danger">주문하기</button>
</div>
</div>
</div>
);
};
export default DetailPage;
let {id} = useParams();
useParams는 React Router에서 제공하는 훅 중 하나로, URL 경로에서 동적으로 전달된 매개변수들을 추출할 때 사용된다. 즉, 현재 경로에서 동적인 부분을 추출하여 사용할 수 있다는 것이다.
ex) /detail/:id 와 같은 경로에서 id에 해당하는 값을 추출하는 데 사용, /detail/123인 경우, id 값은 '123'+ 위 코드는 객체 분해 문법 사용
❗️desserts 라는 state를 Detail.js에서 만들지 않고 굳이 prop 하는 이유
: 만약 나중에 수정 사항이 생겼을 경우, prop 하지 않으면 두 파일을 모두 수정해야 하기 때문에 번거로워지기 때문
❗️❗️ 위 상황에서 만약 임의의 조작을 통해 자료의 순서가 변경된다면 상세 페이지는 어떻게 될까?
: 현재는 [id] 로 데이터 바인딩이 되어 있기 때문에 자료의 순서가 변경되면 상세 페이지의 내용도 따라서 변경된다. 이를 방지하고 싶다면 각 자료마다 고유의 값을 부여해주고 이를 토대로 데이터바인딩하면 된다.
/* Data.js */
let data = [
{
id : 0,
title : "strawberry tart",
content : "Born in France",
price : 20000
},
{
id : 1,
title : "mini pies",
content : "Born in Seoul",
price : 15000
},
{
id : 2,
title : "Creme Brulee",
content : "Born in the States",
price : 10000
}
]
export default data;
import React from "react";
import { useParams } from "react-router-dom";
const DetailPage=(props)=> {
let {id} = useParams();
// useParams에서 가져온 id는 문자열 형태이므로 형변환을 해줘야 함
const imageNum = Number(id) + 1;
const imageUrl = `${process.env.PUBLIC_URL}/img/col${imageNum}.jpg`;
// id와 일치하는 desserts 배열의 요소를 찾아서 productId 변수에 할당
let productId = props.desserts.find(element => element.id == id)
return (
<div className="container">
<div className="row">
<div className="col-md-6">
<img src={imageUrl} width="100%" />
</div>
<div className="col-md-6">
<h4 className="pt-5">{productId.title}</h4>
<p>{productId.content}</p>
<p>{productId.price}</p>
<button className="btn btn-danger">주문하기</button>
</div>
</div>
</div>
);
};
export default DetailPage;
let productId = props.desserts.find(element => element.id == id)
<h4 className="pt-5">{productId.title}</h4>
<p>{productId.content}</p>
<p>{productId.price}</p>



완성!