안녕하세요
9월28일89일차 - React 장바구니 구현 (저장 X) 본문
API로 데이터를 받아와 itm에 저장합니다.
const [itm, setItm] = useState();
useEffect(() => { // useEffect로 데이터를 바로 불러옵니다.
const url = "https://desipossa.github.io/shop_cra/assets/data.json";
const getProduct = async () => {
const res = await axios.get(url); // axios를 이용합니다.
const shopdata = res.data.slice(50, 140).map((it) => { // shopdata 변수에 데이터 배열을 저장합니다.
return {
id: it.id,
name: it.name,
src: it.image_link,
brand: it.brand,
};
});
setItm(shopdata); // 데이터를 state에 담습니다.
};
getProduct();
}, []);
<Route path="/shopList" element={<List shopList={itm} />} /> // itm을 출력할 component에 props로 전달합니다.
<List/>에서 props를 받아와 html태그로 만듭니다.
const List = ({ shopList }) => {
return (
<section className='shopList'>
<div className='inner'>
{
shopList.map(it => {
return (
<figure>
<Link to={'/shopItem/' + it.id}> // <Link to={}> 태그로 아이템의 id를 링크로 보냅니다.
<div className="box">
<img src={it.src} alt="" />
</div>
<div className='name'>{it.name}</div>
<div className='des'>{it.des.substring(0, 100)} ...</div>
<div className='price'><span>{it.price.toLocaleString()}</span> 원</div>
</Link>
</figure>
)
})
}
</div>
</section>
아직 링크로 이동한 주소는 존재하지 않기 때문에 이를 Route와 params를 이용해 만들어주도록 합니다.
Route에서 path를 [ path="/shopItem/:아무이름 ] 와 같이 설정하면 /shopItem/1 2 3 a b c... 와 같이
페이지를 무한히 생성해 해당페이지로 이동할 수 있게 됩니다.
(이용자 경험을 위해서는 페이지에 출력할 데이터가 존재하지 않을 경우에는 404페이지로 이동하거나 다른 route로 보내는 방식으로 에러를 처리하도록 합니다.)
<Route
path="/shopItem/:itm"
element={
<Itm shopList={itm} cart={cart} setCart={setCart} />
}
/>
</Routes>
이제 url의 파라미터를 useParams()로 받아와서 아이템 리스트의 it.id와 파라미터가 일치하는 데이터를 찾습니다.
const Itm = ({ shopList, cart, setCart }) => {
const { itm } = useParams();
const navigate = useNavigate();
const matchItm = shopList.find((it) => itm == it.id); // 이 아이템의 id와 파라미터가 일치하는 데이터를 matchItm 변수에 저장합니다.
해당 객체 데이터를 이용해 html태그로 만들어줍니다.
<section className="shopItm">
<div>
<div className="box">
<img src={matchItm.src} alt="" />
</div>
<div className="name">{matchItm.name}</div>
<div className="des">{matchItm.des.substring(0, 100)} ...</div>
<div className="price">
<span>{matchItm.price.toLocaleString()}</span> 원
</div>
장바구니에 담기 기능을 구현합니다.
App.js에서 객체의 데이터를 담을 수 있도록 cart변수를 useState로 만듭니다.
const [cart, setCart] = useState([
{ id: 1, itm: "ssssssssssssssssssss", price: 5000 },
]);
Route로 /cart 페이지를 만듭니다.
<Route path="/cart" element={<Cart cart={cart} />} />
Itm페이지에서 cart의 데이터를 갱신해줄 것입니다.
<Itm shopList={itm} cart={cart} setCart={setCart} /> 로 props를 전달합니다.
button을 만들어 setCart로 cart에 담겨져 있는 데이터에 새로운 데이터를 저장시킵니다.
navigate 함수를 이용하여 /cart 페이지로 이동하게 합니다.
<button
onClick={() => {
setCart([
...cart, // cart 객체에 담겨있던 데이터를 먼저 입력하지 않으면, 기존의 데이터를 새 데이터가 덮어씌워 추가하지 못하게 돼버립니다.
{ id: matchItm.id, itm: matchItm.name }, // 새로운 데이터를 추가합니다.
]);
navigate("/cart");
}}
>
장바구니 담기
</button>
cart에 저장 된 데이터를 <Cart />컴포넌트에서 map함수를 이용해 html로 펼쳐줍니다.
/cart 페이지에 새로 입력된 정보들이 쌓이게 됩니다.
const Cart = ({ cart }) => {
return (
<div style={{ paddingTop: "500px" }}>
{cart.map((ca) => {
return (
<ul>
<li>{ca.id}</li>
<li>{ca.itm}</li>
<li>{ca.price}</li>
</ul>
);
})}
</div>
);
};
'프론트엔드 국비교육' 카테고리의 다른 글
9월30일93일차 - React 영화진흥위원회 API 불러오기 (0) | 2022.09.30 |
---|---|
9월28일91일차 - React 탭메뉴에 route 붙이기 (0) | 2022.09.30 |
옵셔널 체이닝 ?. (0) | 2022.09.28 |
9월26일87일차 - params route 생성, fetch api 데이터 받아오기 (0) | 2022.09.28 |
9월20일83일차(2) - 리액트 라우터, scss, module.css, 깃허브페이지 라우터 (0) | 2022.09.20 |