[React] 다중 체크박스 구현하기
본문 바로가기
더 알아보기/기능

[React] 다중 체크박스 구현하기

by 은돌1113 2022. 7. 7.
 

[react] 체크박스 구현 (ft. 전체 선택, 전체 해제)

react에서 체크박스 부분 체크, 전체 체크, 전체 해제 구현입니다. 구현 영상 부모 컴포넌트 import React, { useState } from 'react'; import MealTimeCard from './MealTimeCard'; const MealChooseCard = ()..

goddino.tistory.com


기존에 구현했던 checkbox를... 활용해서 이번에도 그걸로 다중 checkbox를 만들 생각이였는 데 5시간 정도 헛발짓 하다가 그냥 내가 만들었다. 위에 있는 블로그를 보고 따라 했었는 데 나중에라도 해결 된다면 남기고 싶어서 남겨본다..
지식인이랑 OKKY랑 맨날 들어가서 확인 해본다😡😡

 

[부모 컴포넌트]

const [checkedItems, setCheckedItems] = useState([]); // 현재 선택된 크레딧 정보 (배열)
const [allCheckedState, setAllCheckedState] = useState(false); // 전체 선택일 경우 true, 개별 선택일 경우 false

const datas = [{ idx: 1 }, { idx: 2 }, { idx: 3 }];

// 전체 선택 or 전체 해제 시
const allCheckedHandler = (state) => {
if (state) {
  // 전체 선택
  const arr = creditList2.map((item, i) => {
    return String(item.idx);
  });

  setCheckedItems(arr);
  setAllCheckedState(true);
} else {
  // 전체 해제
  setCheckedItems([]);
  setAllCheckedState(false);
}
};

// 개별 선택 시
useEffect(() => {
if (checkedItems.length !== creditList2.length) {
  setAllCheckedState(false);
} else if (checkedItems.length === creditList2.length) {
  setAllCheckedState(true);
}
}, [checkedItems]);

return (
  <div>
    전체 선택/해제
  	<label
      className={allCheckedState ? "checked" : "unChecked"}
      onClick={() => {
        allCheckedHandler(!allCheckedState);
      }}
  	/>
    
    개별 선택/해제
    {datas.map((item, i) => {
      return (
        <MultiCheckBox
          data={String(item.idx)}
          checkedItems={checkedItems}
          setCheckedItems={setCheckedItems}
        />
      );
    })}
  </div>
)

 

[자식 컴포넌트]

import { useState, useEffect } from "react";

const MultiCheckBox = (props) => {
  const { data, checkedItems, setCheckedItems } = props;

  // 개별 checkbox
  const [isChecked, setIsChecked] = useState(false);

  useEffect(() => {
    if (checkedItems.includes(data)) {
      setIsChecked(true);
    } else {
      setIsChecked(false);
    }
  }, [checkedItems]);

  return (
    <label
      className={isChecked ? "checked" : "unChecked"}
      onClick={() => {
        setIsChecked(!isChecked);
        if (checkedItems.includes(data)) {
          const arr = checkedItems.filter((item, i) => {
            if (item !== data) {
              return item;
            }
          });

          setCheckedItems(arr);
        } else {
          setCheckedItems([...checkedItems, data]);
        }
      }}
    />
  );
};

export default MultiCheckBox;

 

[CSS]

/* 멀티 checkbox CSS 부분 */
.hidden {
  display: none;
}

.list .checked,
.list .unChecked {
  position: absolute;
  top: 18px;
}

.checked:before {
  content: "\f00c"; /*폰트어썸 유니코드*/
  font-family: "Font Awesome 5 free"; /*폰트어썸 아이콘 사용*/
  font-weight: 600; /*폰트어썸 설정*/
  font-size: 12px;
  color: #ffffff;
  text-align: center;
  display: inline-block;
  width: 20px;
  height: 20px;
  line-height: 20px;
  background: #038dff 0% 0% no-repeat padding-box;
  vertical-align: middle; /*체크 전과 체크 후 높이 차이 때문에 설정*/
  border-radius: 4px;
}

.unChecked:before {
  content: "\f00c"; /*폰트어썸 유니코드*/
  font-family: "Font Awesome 5 free"; /*폰트어썸 아이콘 사용*/
  font-weight: 600; /*폰트어썸 설정*/
  font-size: 12px;
  color: #a1a1aa;
  text-align: center;
  display: inline-block;
  width: 20px;
  height: 20px;
  line-height: 20px;
  vertical-align: middle; /*체크 전과 체크 후 높이 차이 때문에 설정*/
  background: #ffffff 0% 0% no-repeat padding-box;
  border: 1px solid #e1e1e1;
  border-radius: 4px;
}

댓글