DEV

[React] 체크박스 구현

음대생개발자 2024. 1. 29. 13:54

쇼핑몰 프로젝트 진행시 장바구니 목록 체크박스 구현

 

 

 

 

문제점

  • 처음엔 그냥 input 컴포넌트 자체에서 체크박스 구현하려고 했는데
    물품의 id와 개별로 일치하는 체크박스를 만들어야 하기 때문에
    컴포넌트 자체에서 각각의 input을 구분할 수 있는 방법을 찾기가 어려웠다.
    → map 돌리기 전에 check 된 id만 배열로 넣는 함수를 정의하고 prop으로 전달
  • 전체 체크하는 input과 개별 체크 하는 input을 같은 컴포넌트안에서 처리하려고 함
    → 기능 별로 나누고 check 된 id 배열과 장바구니 담긴 물품(배열)의 갯수가 같으면 true : false

 

 

폴더구조 : Cart > CartItem > CheckboxInput

                  Cart > CartHeader > 전체 체크할 수 있는 input 

 

 

// Cart.jsx



const [checkedItemsId, setCheckedItemsId] = useState([]); // 체크된 id만 담은 배열

// 개별 물품 선택
const checkedSingleItemHandler = (id, checked) => { 
    if (checked) { // e.target.checked 불러오기
        setCheckedItemsId((prev) => [...prev, id]);
    } else setCheckedItemsId(checkedItemsId.filter((itemId) => itemId !== id));
};

// 전체 물품 선택
const checkedAllItemHandler = (allChecked) => { 
    if (allChecked) {
        const allItemsId = cartItem.map((item) => item.productId);
        setCheckedItemsId(allItemsId);
    } else {
        setCheckedItemsId([]); // 전체 물품 체크박스가 false가 될 때 전체 해제
    }
};
...
<CartItemsDiv>
    <CartHeader
        checkedAllItemHandler={checkedAllItemHandler}
        checkedItemsId={checkedItemsId}
        cartItem={cartItem}
    />
    <ul>
        {cartItem &&
            cartItem.map((item, index) => (
                <CartItem
                    key={index}
                    item={item}
                    checkedSingleItemHandler={checkedSingleItemHandler}
                    checkedItemsId={checkedItemsId}
                    cartItem={cartItem}
                    products={products}
                />
            ))}
    </ul>
    <CartCheckedDeleteDiv>
        <Button
            size="120px"
            checkedItemsId={checkedItemsId}
            setCheckedItemsId={setCheckedItemsId}>
            선택 삭제
        </Button>
    </CartCheckedDeleteDiv>
</CartItemsDiv>
...
// CartHeader.jsx
// 전체 선택 체크박스

...
const allCheckboxHandler = (e) => {
    checkedAllItemHandler(e.target.checked);
};
return (
    <CartHeaderDiv>
        <div>
            <CartItemCheckInput
                id="all"
                type="checkbox"
                onChange={allCheckboxHandler}
                checked={cartItem.length === checkedItemsId.length ? true : false}
            />
            ...
        </div>
    </CartHeaderDiv>
)
// CheckboxInput.jsx
// 개별 선택 체크박스

...
const checkInputHandler = (e) => {
    checkedSingleItemHandler(item.productId, e.target.checked);
};
return (
    <>
        <CartItemCheckInput
            type="checkbox"
            id={item.productId}
            onClick={checkInputHandler}
            checked={checkedItemsId.includes(item.productId) ? true : false}
        />
        ...
    </>

 

 

 

 

 

*깃허브 전체 소스코드

https://github.com/super-2th-project-team/shopping-mall-fe/tree/feature/api-cart

*참고 사이트

https://shape-coding.tistory.com/entry/React-%EB%A6%AC%EC%95%A1%ED%8A%B8-Checkbox-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0-%EC%A0%84%EC%B2%B4%EC%84%A0%ED%83%9D%ED%95%B4%EC%A0%9C-%EA%B8%B0%EB%8A%A5