적어도 나는 체크박스 없는 장바구니는 본 적이 없는 것 같다. 적어도 앱이 아닌 웹 페이지에서는.
그만큼 체크박스는 장바구니에서 필수적인 요소 중 하나이다.
상품을 장바구니에 담고 처음 장바구니에 들어가 보면 모든 상품의 체크박스에는 체크가 되어 있다. 그래야 별도의 클릭 없이 바로 결제창으로 넘어갈 수 있기 때문이다. 따라서 초기값은 true로 설정하고 시작해야 한다.
상품의 체크 여부에 따라 결제 총 금액이 실시간으로 변동되기도 하고, 선택 삭제를 누르면 체크되어 있는 모든 상품들이 전부 지워지기도 한다.
먼저 체크박스를 관리할 함수 하나를 만들고,
하위 컴포넌트에 props로 넘겨 전체 선택 버튼과 개별 선택 버튼에 onChange로 넣어준다.
// 개별 체크박스
<input
onChange={e => {
checkValueHandle(product_id, e.target.checked);
}}
checked={is_Checked}
className="cartProductCheck"
type="checkbox"
readOnly
/>
// 전체 체크박스
<input
id="cartCheckAll"
onChange={e => {
checkValueHandle(e.target.id, e.target.checked);
}}
checked={isAllCheck}
className="cartCheckAllBox"
type="checkbox"
readOnly
/>
// onChange함수를 통해 클릭한 체크박스의 아이디와 체크 여부를 인자로 받는다.
// 체크박스 관리 함수
const checkValueHandle = (id, checked) => {
// 하위 컴포넌트에서 받은 인자를 가져온다.
const productIdx = products.findIndex(product => product.product_id === id);
// findIndex함수를 통해 아이디가 일치하는 인덱스 값을 구한다.
if (typeof id === 'number') {
// 만일 받아온 아이디값이 숫자라면 개별 상품의 체크박스이므로
const newProducts = [...products];
newProducts[productIdx].is_Checked = checked;
setProductUpdate(newProducts);
// 목데이터를 한번 복사한 후 해당 인덱스의 checked 여부를 바꾸고 업데이트 시킨다.
} else {
// 아니라면 전체 체크박스이므로
const newProducts = [...products];
newProducts.map(product => (product.is_Checked = checked));
setProductUpdate(newProducts);
// map 함수를 통해 남아있는 모든 개별 상품을 한번씩 돌면서 체크 여부를 전체 체크박스의 체크여부와 동일시 한다.
}
};
const isAllCheck =
products.length !== 0 &&
products.filter(product => product.is_Checked === true).length ===
products.length;
// 또한 전체 체크박스의 체크 여부는 개별 체크박스에도 영향을 받는다. 전체 체크박스를 클릭하지 않아도 개별 상품이 전부 체크되어 있으면 true가 되고, 하나라도 체크가 풀리면 전체체크박스는 false로 변하게 된다.
// 따라서 만일 전체 장바구니 상품이 0개가 아니라면, 장바구니 상품에 filter를 돌려서 체크박스가 true인 것만 골라 낸 후 그 상품의 개수가 전체 상품의 개수가 동일한지 검사한다. 동일하면 true, 아니면 false로 변수에 담아 전체 체크박스의 checked 속성 여부로 전달한다.