- 체크박스
- 체크박스를 통해 상품 전체 선택, 전체 해제 구현합니다.
- 상품별 개별 선택, 개별해제(개별선택을 모두 일치 시 전체선택 또는 전체해제로 동작)를 구현합니다.
- 선택된 제품들의 금액들은 주문명세에서 상품 총금액으로 합해져서 보입니다.
- 수량 변경
- 제품별 금액은 제품정보 내에서 보이고 수량을 변경하면 제품별 금액이 수량에 따른 금액으로 업데이트됩니다.
- 서버와의 통신
- 서버 장바구니 테이블에서 데이터를 전달받아서 장바구니 명세에 렌더링합니다.
- 구매하려는 제품들을 선택하고 주문결제 버튼을 누르면 선택된 제품들의 데이터를 서버로 전달합니다.
const checkSingle = (checked, id) => {
checked
? setCheckItems(prev => [...prev, id])
: setCheckItems(checkItems.filter(item => item !== id));
};
<input
className="check-box"
type="checkbox"
onChange={e => checkSingle(e.target.checked, id)}
checked={checkItems.includes(id)}
/>
const checkAll = checked => {
checked
? setCheckItems(cartList?.map(item => item.foodId))
: setCheckItems([]);
};
<input
id="check-all"
className="check-box"
type="checkbox"
onChange={e => checkAll(e.target.checked)}
checked={checkItems.length === cartList?.length}
/>
<label htmlFor="check-all" className="select-all">
전체 선택
</label>
let selectList = [];
const totalPrice = orderPrice * quantityChange;
useEffect(() => {
if (checkItems.includes(id)) {
const selectCancle = selectList.filter(item => item.id !== id);
selectList = selectCancle;
let selectAdd = {};
selectAdd = {
id: id,
sum: totalPrice,
};
selectList = [...selectList, selectAdd];
} else {
const selectCancle = selectList.filter(item => item.id !== id);
selectList = selectCancle;
}
const priceSum = selectList.reduce(
(accumulator, currentValue) => accumulator + currentValue.sum,
0
);
setProductPrice(priceSum);
}, [checkItems]);
<div className="price-info order-price">
<span>상품 금액</span>
<span>{productPrice.toLocaleString()}원</span>
</div>
코드에 관해 쓰기 전에 반성부터 합니다. 이거는 하위 컴포넌트에서 작성했으면 안 됐어.........
반성부터 한 이유는 총 결제 금액을 표시하려고 작성한 코드가 map매서드로 생성되는 하위 컴포넌트에 있어서 전체 리스트가 계산되는 게 아니게 됐다. 계속 초깃값으로 리셋되면서 해당 제품에 대한 금액만 표시되고 결과적으로 마지막 제품의 결제 금액이 표시됐다. 디버깅으로는 리스트에 대한 변수를 전역변수로 선언해서 해결했는데 상수 데이터가 아니고서는 전역변수는 예측불가능해서 에러를 발생하기 때문에 지양해야 하므로 리팩토링이 필요하다.