-
리액트에서 다수의 체크 박스 다루기React.js & Next.js 2022. 9. 13. 22:25
우리는 사용자에게 선택지를 제공할 때 <input type=”radio”> 또는 <input type=”checkbox”> 등을 사용한다. radio의 경우 여러 개의 선택지 중 한 가지를 선택해야 할 때 주로 사용하고, checkbox의 경우 여러 개의 선택지 중 중복 선택이 가능할 때 주로 사용된다고 볼 수 있다.
<form>을 통해 유저의 인터렉션(클릭 이벤트)을 캐치하여 데이터를 생성해야 할 때, checkbox는 사용자의 선택을 배열로 관리하여 데이터화한 이후, 서버 또는 데이터 베이스에 저장하기 유용한 자료구조이다.
이번에는 리액트 프레임워크에서 <input type=”checkbox”> 를 통해 체크 여부를 배열 데이터로 관리하는 방법을 배워볼까 한다.
준비
기본적으로 string으로 구성된 더미 배열을 생성한다. jsx 문법 내부에 생성할 경우, 지속적으로 리 렌더링 되며 초기화될 수 있으므로 컴포넌트 윗부분에 작성하도록 한다.
const checkBoxList = ['Apple', 'Banana', 'Pare', 'Grape', 'Melon', 'Water Melon', 'Pineapple '];
해당 checkBoxList의 더미 데이터를 바탕으로 Array.prototype.map() 메서드를 통해 화면에 렌더링한다.
<div className='checkbox-group'> {checkBoxList.map((item, idx) => ( <div className='checkbox' key={idx}> <input type='checkbox' id={item} /> <label htmlFor={item}>{item}</label> </div> ))} </div>
체크박스 이해하기
기본적으로 checkbox의 check 여부는 <input type=”checkbox” check={???}/> input의 프로퍼티 중 하나인 check 속성을 통해 알 수 있다. input의 해당 check 속성 중 체크된 상태의 element를 배열로 관리하는 로직을 구성해야 한다.
checkBoxList 배열 중 check 된 element를 관리할 useState를 생성한다.
const [checkedList, setCheckedList] = useState<string[]>([]);
또한 해당 element가 체크된 상태인지 파악하기 위한 useState를 생성한다.
const [isChecked, setIsChecked] = useState(false);
이제 input을 클릭했을 때, checkedList라는 useState 배열에 해당 element가 포함되어있지 않다면 추가하고 checkedList 배열에 이미 포함되어 있다면 해당 배열에서 제거하는 handler 함수를 만들어 준다.
const checkedItemHandler = (value: string, isChecked: boolean) => { if (isChecked) { setCheckedList((prev) => [...prev, value]); return; } if (!isChecked && checkedList.includes(value)) { setCheckedList(checkedList.filter((item) => item !== value)); return; } return; }; const checkHandler = (e: React.ChangeEvent<HTMLInputElement>, value: string) => { setIsChecked(!isChecked); checkedItemHandler(value, e.target.checked); };
React.ChangeEvent<HTMLInputElement> 내부 이벤트를 통해 해당 Input 엘리먼트가 체크됐는지 여부를 파악할 수 있다.
해당 checkHandler를 input에 연결한다.
<div className='checkbox-group'> {checkBoxList.map((item, idx) => ( <div className='checkbox' key={idx}> <input type='checkbox' id={item} checked={checkedList.includes(item)} onChange={(e) => checkHandler(e, item)} /> <label htmlFor={item}>{item}</label> </div> ))} </div>
코드를 보면 checked 프로퍼티에 checkedList.includes(item) includes라는 메서드를 통해 체크 여부를 파악하는 것을 알 수 있다. includes는 Array.prototype.includes()로 내부에 해당 요소(element)가 존재할 경우 (포함된 경우) true를 반환한다 우리는 map을 통해 input을 렌더링하고 있기 때문에 각 요소(element) 별로 checkedList에 포함되어 있다면 checked 상태로 보일 것이다.
해당 로직에 form 태그를 연결하여 결과적으로 원하는 값이 잘 담기는지 확인한다.
const onSubmit = useCallback( (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); console.log('checkedList:', checkedList); }, [checkedList] ); ... <div> <h1>Fruits list</h1> <form onSubmit={onSubmit}> <div className='checkbox-group'> {checkBoxList.map((item, idx) => ( <div className='checkbox' key={idx}> <input type='checkbox' id={item} checked={checkedList.includes(item)} onChange={(e) => checkHandler(e, item)} /> <label htmlFor={item}>{item}</label> </div> ))} </div> <button type='submit'>submit</button> </form> </div>
결과 확인하기
최종 코드
import { useCallback, useState } from 'react'; const checkBoxList = ['Apple', 'Banana', 'Pare', 'Grape', 'Melon', 'Water Melon', 'Pineapple ']; const CheckBoxes = () => { const [checkedList, setCheckedList] = useState<string[]>([]); const [isChecked, setIsChecked] = useState(false); const checkedItemHandler = (value: string, isChecked: boolean) => { if (isChecked) { setCheckedList((prev) => [...prev, value]); return; } if (!isChecked && checkedList.includes(value)) { setCheckedList(checkedList.filter((item) => item !== value)); return; } return; }; const checkHandler = (e: React.ChangeEvent<HTMLInputElement>, value: string) => { setIsChecked(!isChecked); checkedItemHandler(value, e.target.checked); console.log(value, e.target.checked); }; const onSubmit = useCallback( (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); console.log('checkedList:', checkedList); }, [checkedList] ); return ( <div> <h1>Fruits list</h1> <form onSubmit={onSubmit}> <div className='checkbox-group'> {checkBoxList.map((item, idx) => ( <div className='checkbox' key={idx}> <input type='checkbox' id={item} checked={checkedList.includes(item)} onChange={(e) => checkHandler(e, item)} /> <label htmlFor={item}>{item}</label> </div> ))} </div> <button type='submit'>submit</button> </form> </div> ); }; export default CheckBoxes;
영상으로 확인하기
콘솔 로그 값 확인하기
'React.js & Next.js' 카테고리의 다른 글
Next.js - SSR, getServerSideProps 적용하기 (0) 2022.09.18 Next.js - 초기화 이후 기본 구조 설정하기 (0) 2022.09.18 스타일드 컴포넌트 조건부 렌더링 활용하기 (0) 2022.08.26 자바스크립트 프로젝트에 타입스크립트 도입하기 (0) 2022.08.24 리액트 18 > 17 마이그레이션하기 (0) 2022.08.23