[리액트] 체크박스 전체 해제

임승민·2022년 9월 6일
0

위엔비 프로젝트

목록 보기
1/5
post-thumbnail

구현 목표
1. 체크된 편의시설은 특정 배열에 담긴다.
2. 체크를 해제하면 배열에서 제거된다.
3. 전체 해제 버튼으로 체크된 편의시설을 해제하며,
4. 체크된 편의시설을 담는 배열을 비운다.

상수 데이터

//부모 컴포넌트
const AMENITIES_LIST = [
  { id: 1, name: '당구' },
  { id: 2, name: '무료주차' },
  { id: 3, name: '바베큐' },
  { id: 4, name: '세탁기' },
  { id: 5, name: '수영장' },
  { id: 6, name: '실내 벽난로' },
  { id: 7, name: '야외 샤워 시설' },
  { id: 8, name: '엽무전용' },
  { id: 9, name: '에어컨' },
  { id: 10, name: '온수 욕조' },
  { id: 11, name: '와이파이' },
  { id: 12, name: '운동 기구' },
  { id: 13, name: '유료주차' },
  { id: 14, name: '주방' },
  { id: 15, name: 'TV' },
  { id: 16, name: '패티오' },
  { id: 17, name: '화로' },
  { id: 18, name: '야외 식사 공간' },
];

BE와 통신하기 전 임의로 데이터를 생성하였다.

부모 컴포넌트

//부모 컴포넌트
const [checkedList, setCheckedList] = useState([]); // check된 편의시설 담는 배열

  const addCheckedList = (amenitiedInfo, checked) => { // 자식이 인자를 넘겨준다.
    checked 
      ? setCheckedList([...checkedList, { ...amenitiedInfo }]) //true면 배열에 담는다.
      : setCheckedList(
          checkedList.filter(check => {
            return check.id !== amenitiedInfo.id; //false면 배열에서 제거한다.
          })
        );
  };

  const ckedListReset = () => {
    setCheckedList([]); // 배열 전체를 비운다.
  };
  • 부모에서 checked값이 true인 편의시설만 담는 checkedList가 있다.
  • addCheckedList함수 인자로 체크를 변경한 해당 편의시설의 객체와 체크여부가 들어온다.
  • 해당 편의시설의 checked가 true면 checkedList배열에 담고, false라면 Filter를 사용해서 checkedList배열에서 제거한다.
  • checkedListReset함수가 실행되면 checkedList를 빈배열로 만든다.

자식 컴포넌트

부모에서 데이터를 map을 돌려 자식 컴포넌트에게 props로 전달한다.

//부모 컴포넌트
{AMENITIES_LIST.map(info => {
  return (
    <FilterCheckSingle
      key={info.id}
      amenitiedInfo={info}
      addCheckedList={addCheckedList}
      checkedList={checkedList}
    />
  );
})}

자식은 부모로부터 amenitiedInfo, addCheckedList, checkedList 를 받는다.

//자식 컴포넌트
const FilterCheckSingle = ({ amenitiedInfo, addCheckedList, checkedList }) => {
  
	const checkedListId = checkedList.map(item => item.id); //checkedList의 id값만 추출한다.

  return (
    <FilterCheckSingleWrap>
      <FilterSingleCheckBox
        type="checkbox"
        checked={checkedListId.includes(amenitiedInfo.id)} //checkedListId에 해당 자식의 id가 존재하는지 확인
        onChange={e => {
          addCheckedList(amenitiedInfo, e.target.checked);
        }}
      />
      <FilterAmenitiedName>{amenitiedInfo.name}</FilterAmenitiedName>
    </FilterCheckSingleWrap>
  );
};

checked의 속성값으로 들어있는 코드는 아래와 같다.

  1. checkedList의 id 값만 추출한 checkedListId 변수를 만든다.
  2. checkedListId에서 includes를 이용해서 해당 상품의 Id값이 존재 하는지 검사한다.
  3. 존재한다면 true, 없다면 false를 반환하여 checked의 속성값을 동적으로 변경한다.
  4. 부모 컴포넌트에서 checkedListReset 이라는 checkedList를 빈배열로 만드는 함수가 실행된다면
  5. checkedListId 에는 아무값이 없기 때문에 Includes 를 돌려도 false만 나온다.
  6. 따라서 모든 편의시설 checked 속성은 false값을 얻게된다.

마치며

1차 프로젝트 때 체크박스 관련 기능을 구현 했지만 그 때와는 또 다른 느낌의 기능이라 조금 헤매기는 하였으나 저번 보다는 조금 수월하게 구현을 할 수 있어서 좋았고, 3~4시간 정도 안풀리던 부분을 혹시나 해서 includes를 사용했더니 너무 쉽게 돼서 조금 당황스러웠지만 그래도 구현해내서 상당히 뿌듯했다.

0개의 댓글