리액트에서 checkbox를 다루기(new Set을 곁들인)

Updated:

React에서 체크박스를 구현하기

React 뿐만 아니라 체크박스를 구현하는 예제는 많다. new Set으로 구현하는 방법을 새로 배웠기에 블로그에 기록으로 남긴다.

why new Set?

set()은 value들로 이루어진 집합 Array이와는 다르게 Set은 같은 “value”를 두번 포함이 안된다. 그렇기 때문에 Set에 이미 존재하는 value를 추가하려고 해도 아무일이 없다.

특정요소 추가 : add 특정 요소가 있는지 확인 : has() boolean값으로 반환 특정 요소 제거 : delete 모든 요소 제거 : clear 요소의 개수 반환 : size (배열의 length)

new Set을 코드에서 적용해보자!

// 새로운 set을 만들고
let setA = new Set();

// 새로운 set을 만들고 인자로 전달된
let setB = new Set().add("a").add("b");
setB.add("c");

console.log(setB.size); // 3

// has(): 준 값이 set 안에 존재하면, true를 반환

// delete : set에서 주어진 값을 제거
setB.delete("b");
console.log(setB.has("b"));

// clear : 모든 데이터를 제거
setB.clear();
console.log(setB.size); // 0

예제

중복값 제거하기

new Set으로 받은 값을 배열에 담기 위해서는 비구조화 할당을 이용하면 된다!

const numbers = [1, 2, 3, 4, 2, 5, 6, 7, 7];
const result = [...new Set(numbers))] // 중복이 제거된 값이 나오게 된다.

자 이제 new Set이 어떤 상황에서 쓰이며 기능적으로 사용방법을 알았기에 실제 코드에 적용해보도록 하자.

상위 코드

import React, { useState } from "react";
import CheckboxChild from "./CheckboxChild";

const Checkbox = () => {
  const formData = [
    { id: 1, name: "a" },
    { id: 2, name: "b" },
    { id: 3, name: "c" },
    { id: 4, name: "d" },
    { id: 5, name: "e" },
    { id: 6, name: "f" },
    { id: 7, name: "g" }
  ];
  const [checkedItem, setCheckedItem] = useState(new Set()); // 체크된 아이템

  const checkedItemHandler = (id, isChecked) => {
    // 해당 체크박스가 체크가 되었을 때
    if (isChecked) {
      checkedItem.add(id); // 해당 id저장(input value값 삽입)
      setCheckedItem(checkedItem); // 체크 요소 넣어주기
      console.log(checkedItem, "CCC");
    }
    // 체크가 안되었고, 해당 체크박스 두번 누를경우
    else if (!isChecked && checkedItem.has(id)) {
      checkedItem.delete(id); // 체크 두번일 경우 삭제
      setCheckedItem(checkedItem);
    }
    return checkedItem;
  };

  console.log(checkedItem, "checkedItem");

  return (
    <>
      <ul>
        <li>
          {formData.map((item, idx) => {
            return (
              <label key={idx}>
                <CheckboxChild
                  item={item}
                  checkedItemHandler={checkedItemHandler}
                  checkedItem={checkedItem}
                />
                <div>{item.name}</div>
              </label>
            );
          })}
        </li>
      </ul>
    </>
  );
};
export default Checkbox;

자식 코드

import React, { useState } from "react";

const CheckboxChild = ({ item, checkedItemHandler, checkedItem }) => {
  const [isChecked, setIschecked] = useState(false); // 체크여부

  // target은 event의 디스트럭처링
  const checkHandler = ({ target }) => {
    setIschecked(!isChecked);
    console.log(target.value, "target");
    console.log(target.parentNode, "node"); //해당 상위 label element
    console.log(target.checked, "checked"); //해당 체크를 확인(boolean값으로 출력)
    const { checked } = target;
    checkedItemHandler(item.id, checked);
  };
  console.log(checkedItem, "III");
  return (
    <>
      <input
        key={item.id}
        type="checkbox"
        value={item.name}
        onChange={(e) => checkHandler(e)}
      />
      <div>{checkedItem}</div>
    </>
  );
};

export default CheckboxChild;

추가 예제


  const [length, setLength] = useState(null);

  const isChecked = (id) => {
    const isIncludes = checkListItem.includes(id);

    return isIncludes;
  };

  const addRemoveDisplay = (e, program) => {
    e.stopPropagation();
    const a = checkListItem.some((el) => el === program);
    if (checkListItem === [] || !a) {
      setCheckListItem([...checkListItem, program]);
    } else {
      const arr = checkListItem.filter((el) => el !== program);
      setCheckListItem(arr);
    }
  };

  const selectAllPrograms = () => {
    const allArr = listData.map((el) => el.notice_id);
    if (checkListItem.length === allArr.length) {
      setCheckListItem([]);
    } else {
      setCheckListItem(allArr);
    }
  };

  // *************** 전체 선택이 가능한 체크박스 view ************************
    <CFormGroup
    variant="checkbox"
    className="checkbox"
    onClick={selectAllPrograms}
  >
    <CInputCheckbox
      name="all"
      value="all"
      checked={checkListItem.length === length}
    />
    <CLabel
      variant="checkbox"
      className="form-check-label"
      htmlFor="akk"
    ></CLabel>
  </CFormGroup>


  // ******************* 일반 선택이 가능한 체크박스 view ******************************
    <CFormGroup variant="checkbox" className="checkbox">
    <CInputCheckbox
      name={rowNumber}
      value={rowNumber}
      onClick={(e) => addRemoveDisplay(e, notice_id)}
      checked={isChecked(notice_id)}
    />
    <CLabel
      variant="checkbox"
      className="form-check-label"
      htmlFor={rowNumber}
    ></CLabel>
  </CFormGroup>

배운점

es6부터 나온 new set을 이용한 적이 드물어 어떠한 상황에서 쓰일지 잘 몰랐는데 해당 소스코드를 직접 사용해 봄으로서 좀 더 알게 되었다. 다음 실무 프로젝트에서는 실제로 적용하여 사용해 볼 수 있을 거 같다.

참고

글쓰는 개발자 갓디노

Tags:

Categories:

Updated: