(멋있는 짤이다 !!)
checkbox 가 4개일 때... 그리고 checkbox 가 50개일 때
같은 방법으로 쓸 순 없다 .,,,!checkbox 전체 선택 코드 개선해보기 !
input이 폭포처럼 쏟아지는 프로젝트를 맡다보니...
더 효율성 있는 방법을 찾아보고...알아보고 한 끝에 너무 간단한 방법 발견했다
const [checked, setChecked] = useState<boolean[]>([
false,
false,
false,
false,
]);
const handleChangeAll = (event: ChangeEvent<HTMLInputElement>) => {
setChecked([
event.target.checked,
event.target.checked,
event.target.checked,
event.target.checked,
]);
};
const handleChangeProvision = (event: ChangeEvent<HTMLInputElement>) => {
setChecked([event.target.checked, checked[1], checked[2], checked[3]]);
};
const handleChangePrivacy = (event: ChangeEvent<HTMLInputElement>) => {
setChecked([checked[0], event.target.checked, checked[2], checked[3]]);
};
const handleChangeUnique = (event: ChangeEvent<HTMLInputElement>) => {
setChecked([checked[0], checked[1], event.target.checked, checked[3]]);
};
const handleChangePromotion = (event: ChangeEvent<HTMLInputElement>) => {
setChecked([checked[0], checked[1], checked[2], event.target.checked]);
};
const isDisabled = !(
checked[0] === true &&
checked[1] === true &&
checked[2] === true
);
흠 .. 정말 길다.
겨우 네개의 체크박스를 전체 선택, 개별 선택하는 것 뿐인데 좀 하드하다.
그런데 만약 체크박스가 네개가 아니라 50개라면 이를 다 이렇게 할 건 아니잖아요.
checkbox 가 50개씩, 10개의 폼을 만든다고 가정할 때,
재사용할 수 있도록 컴포넌트화해서 사용해보자.
const [serviceScope, setServiceScope] = useState<string[]>([]);
const [diseases, setDiseases] = useState<string[]>([]);
const handleChangeServiceScope = (e: React.ChangeEvent<HTMLInputElement>) => {
const isChecked = e.target.checked;
const value = e.target?.value;
if (isChecked) {
setServiceScope([...serviceScope, value]);
} else {
setServiceScope(serviceScope.filter((x: string) => x !== value));
}
};
const handleServiceScopeAllCheck = (checked: boolean) => {
if (checked) {
const newArr: string[] = [];
ServiceScope.forEach((el) => newArr.push(el.name));
setIndustries(numArray);
} else {
setIndustries([]);
}
};
handleChangeServiceScope() 함수를 만들어, checkbox 의 onChange 이벤트를 걸고 해당 값을 toggle 시 배열 안에 넣거나 뺀다.
<Stack direction="row" alignItems="center" mb={5}>
<Checkbox
onChange={(e) => handleServiceScopeAllCheck(e.target.checked)}
checked={serviceScope.length === ServiceScope.length}
}
/>
<Typography fontSize="1.5rem" color="text.secondary">
전체선택
</Typography>
</Stack>
.
.
.
<Checkbox
key={item.num}
value={item.name}
checked={serviceScope.includes(String(item.name))}
onChange={(e: React.ChangeEvent<HTMLInputElement>,) => handleChangeServiceScope(e)} />
전체 선택 체크박스를 누르면 map 으로 돌린 checkbox 가 모두 check 표시 된다.
serviceScope 배열에 해당 체크박스의 값이 들어있는지의 여부를 판단해서 체크 표시
export function AllCheckBox({ handleChange, arr, state }: Props) {
return (
<Stack direction="row" alignItems="center" mb={5}>
<Checkbox
onChange={(e) => handleChange(e.target.checked)}
checked={state.length === arr.length}
icon={
<img src={sCheckBoxOff} alt="checkOff" style={{ width: '18px' }} />
}
checkedIcon={
<img src={sCheckBoxOn} alt="checkOn" style={{ width: '18px' }} />
}
/>
<Typography fontSize="1.5rem" color="text.secondary">
전체선택
</Typography>
</Stack>
);
이렇게 컴포넌트를 만들어서,
전체선택 체크박스를 사용하고자 하는 곳에 <AllCheckBox />
를 갖다 쓰면 된다.
handleChange props 로 위의 전체선택 함수를, arr props 로는 50개의 데이터가 담겨있는 배열을, state props 로는 빈 배열의 state 를 전달해주면 끝!!!
아주 간단합니다