안녕하세요
1주차 과제 장바구니(2) - 장바구니에 추가, 삭제, 수량 조절, 전체가격 표시 본문
[1주차 과제 장바구니 사이트] (2023-01-13 ~ 2023-01-18 약 일주일)
React App
youngentry.github.io
- 1주차 과제 장바구니(1) - css 구현하기
- 1주차 과제 장바구니(2) - 장바구니에 추가, 삭제, 수량 조절, 전체가격 표시
- 1주차 과제 장바구니(3) - 장바구니 비우기, 금액초과 경고, 입력값 검사
- 1주차 과제 장바구니(완료) - 모달창 다음 단계로, 드래그 기능
장바구니에 제품 추가하기
1. 장바구니를 렌더링하기 위한 리스트를 만든다.
const [cartList, setCartList] = useState([]);
2. 삼항연산자를 이용해 장바구니에 상품이 있을 때, 없을 때를 나누어 표시한다.
{cartList.length ? (
cartList.map((cartItem, index) => {}
) : (
<span>장바구니에 담긴 상품이 없습니다.</span>
)}
3. 장바구니에 추가 버튼을 클릭하면 선택된 제품의 id를 전달하는 함수를 만든다.
<Button variant="primary" onClick={() => addItemIntoCartList(data.id)}>
장바구니에 추가
</Button>
4. find() 메서드를 이용하여 선택된 제품의 id와 일치하는 제품을 데이터에서 찾는다.
// ----- 장바구니에 제품 추가하기 -----
const [cartList, setCartList] = useState([]);
const [idSelectedItem, setIdSelectedItem] = useState(null);
const addItemIntoCartList = (id) => {
// id와 같은 제품을 데이터에서 찾기
setIdSelectedItem(id);
const itemFoundByIdFromShoesData = shoesData.find((shoes) => shoes.id === id);
// ----- 장바구니에 제품 추가하기 -----
=> find() 메서드를 이용한 id와 일치하는 데이터 찾기
5. 장바구니 데이터에는 수량을 더하여 업데이트한다.
// ----- 장바구니에 제품 추가하기 -----
const [cartList, setCartList] = useState([]);
const [idSelectedItem, setIdSelectedItem] = useState(null);
const addItemIntoCartList = (id) => {
// id와 같은 제품을 데이터에서 찾기
setIdSelectedItem(id);
const itemFoundByIdFromShoesData = shoesData.find((shoes) => shoes.id === id);
// cartList 데이터 업데이트하기 (있으면 수량++, 없으면 상품목록에 추가)
if (itemFoundByIdFromShoesData.amount) {
return (itemFoundByIdFromShoesData.amount += 1);
}
itemFoundByIdFromShoesData.amount = 1;
setCartList([...cartList, itemFoundByIdFromShoesData]);
};
// ----- 장바구니에 제품 추가하기 -----
=> 데이터의 속성에 amount가 존재한다면 값을 +1 해준다.
=> 그렇지 않을 때는 데이터의 속성에 amount = 1 이라는 값을 추가한다.
=> cartList를 업데이트한다.
수량 조정 기능 구현하기
1. +를 클릭하면 숫자가 올라가고, -를 클릭하면 숫자가 내려가는 함수를 만든다.
<Button variant="primary" onClick={() => plusCartItemAmount(cartItem.id, false)}>
-
</Button>
<Button variant="light">{cartItem.amount}</Button>
<Button variant="primary" onClick={() => plusCartItemAmount(cartItem.id, true)}>
+
</Button>
=> plusCartItemAmount 함수는 id와 boolean 값을 전달한다.
2. cartList의 데이터를 업데이트한다.
// ----- 장바구니 제품 "+", "-"로 수량 바꾸기 -----
const plusCartItemAmount = (id, boolean) => {
setIdSelectedItem(id);
const itemFoundByIdFromCartList = cartList.find((cartItem) => cartItem.id === id);
// 수량을 1더하기 한다.
if (boolean) {
return (itemFoundByIdFromCartList.amount += 1);
}
// 수량이 1이상일 때 -1
if (itemFoundByIdFromCartList.amount > 0) {
itemFoundByIdFromCartList.amount -= 1;
}
};
// ----- 장바구니 제품 "+", "-"로 수량 바꾸기 -----
=> 선택한 제품의 id와 일치하는 제품을 cartList에서 찾는다.
=> +버튼을 누르면 true를 전달 받고, 해당 제품 데이터의 amount 속성을 +1로 업데이트한다.
=> -버튼을 누르면 false를 전달받아 +1이 동작하지 않는다.
=> -버튼을 눌렀을 때 수량이 마이너스가 되지 않도록 0보다 클 때만 amount 속성을 -1로 업데이트한다.
3. 장바구니 기능과 관련된 함수가 동작할 때 대부분 id를 이용하므로, id state가 변할 때마다 렌더링 하도록 초기화한다.
// 장바구니 렌더링용 state 변화감지
useEffect(() => {
setIdSelectedItem(null);
console.log(cartList);
}, [idSelectedItem]);
장바구니 리스트에서 삭제하기
1. 버튼을 클릭하면 id를 전달하는 함수를 만든다.
<CloseButton onClick={() => removeCartItem(cartItem.id)} />
2. 선택한 제품을 cartList에서 제외한다.
// ----- 장바구니에서 선택한 제품 삭제하기 -----
const removeCartItem = (id) => {
const tempCartList = [...cartList];
const itemFoundByIdFromCartList = tempCartList.find((tempCartItem) => tempCartItem.id === id);
// 제품 배열에서 제외
tempCartList.splice(itemIndexSelectedByIdFromCartList, 1);
setCartList([...tempCartList]);
};
// ----- 장바구니에서 선택한 제품 삭제하기 -----
=> find()메서드를 이용하여 id로 해당 제품의 index를 찾는다.
=> splice() 메서드를 이용하여 배열에서 해당 제품을 배열에서 제외한 데이터로 업데이트한다.
3. 수량 초기화하기
제품에 amount 속성이 업데이트 되어있었기 때문에 이를 0으로 초기화하지 않으면
제품을 다시 추가할 때 오류가 발생한다.
// cartList 데이터 업데이트하기 (있으면 수량++, 없으면 상품목록에 추가)
if (itemFoundByIdFromShoesData.amount) {
return (itemFoundByIdFromShoesData.amount += 1);
}
itemFoundByIdFromShoesData.amount = 1;
setCartList([...cartList, itemFoundByIdFromShoesData]);
=> amount의 값을 0으로 초기화해주면 조건이 false가 되어 +1 을 하는 것이 아닌
=> 제품 추가하기가 실행된다.
// ----- 장바구니에서 선택한 제품 삭제하기 -----
const removeCartItem = (id) => {
const tempCartList = [...cartList];
const itemIndexSelectedByIdFromCartList = tempCartList.findIndex((tempCartItem) => tempCartItem.id === id);
const itemFoundByIdFromCartList = tempCartList.find((tempCartItem) => tempCartItem.id === id);
// 수량 초기화
itemFoundByIdFromCartList.amount = 0;
// 제품 배열에서 제외
tempCartList.splice(itemIndexSelectedByIdFromCartList, 1);
setCartList([...tempCartList]);
};
// ----- 장바구니에서 선택한 제품 삭제하기 -----
=> find() 메서드를 이용하여 id가 일치하는 제품을 찾아
=> amount 속성을 0으로 초기화한다.
장바구니 전체 가격 나타내기
1. 전체 가격을 구하기 위한 함수를 만든다.
<strong>총 액수 : {getPriceTotalFromCartList(cartList)}원</strong>
2. cartList의 아이템들의 price 속성과 amount 속성의 값을 곱한 값을 반환한다.
// ----- 장바구니에 담긴 아이템 전체가격 -----
const getPriceTotalFromCartList = (itemList) => {
let priceTotal = 0;
itemList.forEach((item) => {
priceTotal += item.price * item.amount;
});
return priceTotal;
};
// ----- 장바구니에 담긴 아이템 전체가격 -----
3. 1,000과 같이 세자리 수마다 콤마를 찍는 함수를 만든다.
/**
숫자 세자리마다 콤마 찍기 위함 ex) 1000 => 1,000
@param number
*/
const getPriceComma = (price) => {
return price.toLocaleString("ko-KR");
};
=> toLocaleString() 메서드를 이용하면 입력받은 숫자(1000)를 세자리 마다 콤마를 넣어(1,000) 표기할 수 있다
4. 구한 전체 값에 콤마를 찍는 함수를 실행한 값을 반환하도록 한다.
// ----- 장바구니에 담긴 아이템 전체가격 -----
const getPriceTotalFromCartList = (itemList) => {
let priceTotal = 0;
itemList.forEach((item) => {
priceTotal += item.price * item.amount;
});
priceTotal = getPriceComma(priceTotal);
return priceTotal;
};
// ----- 장바구니에 담긴 아이템 전체가격 -----
추가목표
컴포넌트를 분리하여 렌더링 범위를 작게 만들기
차후에 리덕스로 이식할 때는 cartList 데이터를 별도로 생성하여
selectedId state가 변할 때마다 전체 화면을 렌더링하지 않도록 한다.
'복습스터디과제' 카테고리의 다른 글
2주차 유튜브 API(1) - 설계 및 css 구현 (0) | 2023.01.20 |
---|---|
1주차 과제 장바구니(완료) - 모달창 다음 단계로, 드래그 기능 (0) | 2023.01.18 |
1주차 과제 장바구니(3) - 장바구니 비우기, 금액초과 경고, 입력값 검사 (0) | 2023.01.14 |
1주차 과제 장바구니(1) - css 구현하기 (2) | 2023.01.14 |
230110 주희 1주차 과제 (0) | 2023.01.10 |