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
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;
반응형
'개발 > React' 카테고리의 다른 글
[react] next.js 사이트 만들기 (ft. getStaticProps, getServerSideProps) ver.1 (0) | 2021.09.08 |
---|---|
[react] Object is possibly 'null' (ft. typescript, style) 오류 해결 (0) | 2021.09.06 |
[react] vs code rsc 입력 후 자동 코드 설치 플로그인 (0) | 2021.09.05 |
[react] pie 차트 (ft. 도넛 차트 라이브러리) (3) | 2021.09.05 |
[react] react-datepicker 커스텀 (0) | 2021.09.02 |
댓글