📌리액트 체크박스 만들기
원하는 결과물
새로운 게시물 등록할 경우에는
영업일을 체크박스로 선택하고 값을 넘겨주도록 만들고자 했다!
등록된 게시물을 수정할 경우에는
게시물 등록 때 체크한 값은 이미 체크되어 있는 상태로 보여주고자 했다!
📌label 태그와 checkbox
<label>
<input type="checkbox" value={index} checked={ischecked} onChange={(e) => onChangeHandler(e)} />
<p>{day}</p>
</label>
label 태그로 감싸진 checkbox는
label을 눌러도 체크가 된다!
체크박스를 보이지 않게 할 것이기 때문에 ( appearance: none )
마치 label 자체를 체크박스 처럼 사용할 수 있다.
그래서 체크가 되었을 때와 안되었을 때 label의 background-color를 다르게 지정해주고자 했다.
문제점
background-color: ${(checked) => {
console.log(checked)
if (checked) {
return '#ffffff';
} else {
return '#777777';
}
}};
<StCheckbox type="checkbox" value={index} checked={checked} onChange={(e) => onChangeHandler(e)} />
styled 컴포넌트로 label을 만들어서
background-color를 정하는데 props를 받아서 이용하고자 했다!
위의 코드처럼 checked라는 props를 전달했는데
console.log(checked) 를 하면 불리언 값이 아니라 객체가 찍혔다.
객체 안에는 children이 있고,
children 안에 props 안에 checked가 불리언 값으로 존재하는 것을 확인했다....!
첫번째 시도
background-color: ${(checked) => {
const { checked } = checked.children[0].props;
if (checked) {
return '#ffffff';
} else {
return '#777777';
}
}};
state로 만들었던 checked와 props에 있는 checked가 이름이 같아서 오류가 발생했다.
해결 방법
<StCheckbox type="checkbox" value={index} checked={ischecked} onChange={(e) => onChangeHandler(e)} />
background-color: ${(ischecked) => {
const { checked } = ischecked.children[0].props;
if (checked) {
return '#ffffff';
} else {
return '#777777';
}
}};
state의 이름을 isChecked로 바꿔서 해결했다!
📌check된 값 저장하기
const days = ['월', '화', '수', '목', '금', '토', '일'];
const [checkItems, setCheckItems] = useState(new Set());
const checkHandler = (index, isChecked) => {
if (isChecked) {
checkItems.add(+index);
setCheckItems(new Set(checkItems));
} else if (!isChecked) {
checkItems.delete(+index);
setCheckItems(new Set(checkItems));
}
};
...
return(
...
{type === 'add' &&
days.map((day, index) => {
return <Checkbox key={index} day={day} index={index} checkHandler={checkHandler} />;
})}
...
)
checkHandler 함수를 만들어서 체크된 값을 중복 없이 저장하도록 한다.
그래서 checkItems state를 만들때 초기값을 new Set()으로 해주었다.
그리고 isChecked 값이 true / false 인 경우를 구분해서
.add와 .delete를 이용했다.
checkItems에 담긴 값은 나중에 사용할 일이 있어서 숫자로 저장하기 위해
+index로 인자를 넘겨줬다.
그렇게 .add / .delete 한 checkItems으로 state를 업데이트 한다!
Checkbox.jsx
const Checkbox = ({ day, index, checkHandler, checkedDay, setCheckItems }) => {
const [ischecked, setischecked] = useState(false);
const onChangeHandler = (e) => {
setischecked(!ischecked);
checkHandler(e.target.value, e.target.checked);
};
return (
<StLabel>
<StCheckbox type="checkbox" value={index} checked={ischecked} onChange={(e) => onChangeHandler(e)} />
<p>{day}</p>
</StLabel>
);
};
export default Checkbox;
const StCheckbox = styled.input`
appearance: none;
`;
const StLabel = styled.label`
cursor: pointer;
margin: 10px;
padding: 8px;
border-radius: 8px;
background-color: ${(ischecked) => {
const { checked } = ischecked.children[0].props;
if (checked) {
return '#ffffff';
} else {
return `var(--color_gray2)`;
}
}};
`;
체크박스 컴포넌트에서
부모 컴포넌트에서 만든 함수인 checkHandler를 사용한다!
참고한 블로그
[React] 리액트에서 Set 이용한 Checkbox 상태관리하기!
0. 소개 프로젝트 작업을 하면서 checkbox가 필요하게 되었고, 다양한 방법중에 Set과 useState를 이용한 방법으로 작업을 해보았습니다. Set과 useState를 이용한 방법을 예제와 함께 정리해보겠습니다 1
shape-coding.tistory.com