본문 바로가기
💻CODING/react. vue

[react] 체크 박스 토글 기능 구현 (ft. new Set(), checked)

by 코딩하는 갓디노 2021. 9. 5.

리액트 체크박스 토글기능

 

react, set 객체를 이용한
체크박스 토글 기능 구현입니다.

 

구현 화면

 

구현 영상

 

 

구현 내용
- react, hooks 방식
- 체크 박스 토글 기능(한번 클릭 선택, 두번 클릭 취소)
- es6 최신 문법, set 객체를 이용하여 체크된 요소들 넣어주기

 

react 체크박스 토글 기능 (new Set())

import React, { useState } from "react";

const Check = () => {
  const formData = [
    { 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: "커피" },
  ];

  const [isChecked, setIsChecked] = useState(false); //체크 여부
  const [checkedItems, setCheckedItems] = useState(new Set());//체크된 요소들

  const checkHandler = ({ target }) => {
    setIsChecked(!isChecked);
    checkedItemHandler(target.parentNode, target.value, target.checked);
  };

  const checkedItemHandler = (box, id, isChecked) => {
    if (isChecked) { //체크 되었을때
      checkedItems.add(id); //체크시 삽입
      setCheckedItems(checkedItems); //체크 요소 넣어주기
      box.style.backgroundColor = "#F6CB44"; //스타일 변경
    } else if (!isChecked && checkedItems.has(id)) { //체크가 안되었고, id가 있을때(클릭 2번시)
      checkedItems.delete(id); //체크 두번시 삭제
      setCheckedItems(checkedItems);
      box.style.backgroundColor = "#fff";
    }
    return checkedItems;
  };

  return (
    <div className="contStyle">
      {formData.map((item) => (
        <label key={item.id} className="innerBox">
          <input
            type="checkbox"
            value={item.name}
            onChange={(e) => checkHandler(e)}
          />
          <div>{item.name}</div>
        </label>
      ))}
    </div>
  );
};

export default Check;

 

콘솔로 확인

 console.log(target.parentNode, target.value, target.checked);
 //1번 클릭시 결과
 //<label className="innerBox">...</label> "딸기" true
 
 console.log(checkedItems);
 //1, 2번 클릭시 결과
 //Set(2) {"딸기", "바나나"} //딸기, 바나나 추가
 //1번 다시 클릭시 결과
 //Set(1) {"바나나"} //딸기 삭제

 

 부모/자식 컴포넌트 분리 예제

부모 컴포넌트

const [checkedItems, setCheckedItems] = useState(new Set());

const onHandleCheckedItems = (id, isChecked) => {
  if (isChecked) {
    checkedItems.add(id);
    setCheckedItems(checkedItems);
  } else if (!isChecked && checkedItems.has(id)) {
    checkedItems.delete(id);
    setCheckedItems(checkedItems);
  }
  console.log('checkedItems', checkedItems)
};

 ...
 return (
 <ul className='flex flex-col gap-2 mt-4'>
  {arrayData.map((row, idx) =>
  <li key={idx}>
    <label className="inline-flex items-center mt-3">
      <InputBox row={row} onHandleCheckedItems={onHandleCheckedItems} />
      <span className="ml-2 text-gray-700">{guide.content}</span>
    </label>
  </li>
  )}
</ul>
 )

 

자식 컴포넌트

import React, { useState } from 'react';

const InputBox = ({ row, onHandleCheckedItems }) => {
    const [bChecked, setChecked] = useState(false);

    const checkHandler = ({ target }) => {
        setChecked(!bChecked);
        onHandleCheckedItems(row.id, target.checked);
    };

    return (
        <>
            <input type="checkbox" checked={bChecked} onChange={(e) => checkHandler(e)}
        </>
    );
};

export default InputBox;

 

set 객체 대한 예제는 아래 포스트로 이동해주세요.

https://goddino.tistory.com/222

 

new Set 중복값 제거

Set 객체 es6 최신 문법의 중복을 제거한 값들의 집합입니다. 특정 요소 추가: add 특정 요소가 있는지 확인: has (boolean 값으로 반환) 특정 요소 제거: delete 모든 요소 제거: clear 요소의 개수 반환: siz

goddino.tistory.com


react 체크박스 토글 기능 (array)

  • 주의할 점은 부모 컴포넌트와 자식 컴포넌트의 함수 선언과 사용을 제대로 해야 합니다. 
  • checkedItemHandler 함수를 자식 컴포넌트에서 선언하고 사용할 경우, checkedItems 배열에 요소가 계속 한개만 들어가있게 됩니다. -> 상위 컴포넌트에서 함수 선언 후 property로 내려줌

부모 컴포넌트

import React, { useState } from 'react';

const Example = () => {
    const [checkedItems, setCheckedItems] = useState([]);//체크된 요소들

    const checkedItemHandler = (box, code, isChecked) => {
        if (isChecked) { //체크 되었을때 
            setCheckedItems([...checkedItems, code])
            box.style.backgroundColor = "#F6CB44"; //스타일 변경
        } else if (!isChecked && checkedItems.find(one => one === code)) { //체크가 안되었고, id가 있을때(클릭 2번시) 
            const filter = checkedItems.filter(one => one !== code)
            setCheckedItems([...filter]);
            box.style.backgroundColor = "#fff";
        }
    };

    console.log('checkedItems', checkedItems)

    return (
       <form>
            {questionLists[i]?.answerList.map((answer, idx) =>
                <CheckCard key={idx} answer={answer} checkedItemHandler={checkedItemHandler} />)}
        </form >
    );
};

export default Example;

 

자식 컴포넌트

input의 id와 label의 htmlFor를 일치시켜야 label 태그 클릭시 해당 checkbox이 연동되어 실행됩니다.

import Reactfrom 'react';

const CheckCard = ({ answer, checkedItemHandler }) => {

    const onCheck = ({ target }) => {
        checkedItemHandler(target.parentNode, target.value, target.checked)
    }

    return (
            <div>
                <input type='checkbox' id={answer.dCode} value={answer.dCode} 
                onChange={e => onCheck(e)} />
                <label htmlFor={answer.dCode} className="text-sm">{answer.name}</label>
            </div>
    );
};

export default CheckCard;
반응형

댓글