이번에 프로젝트를 진행하면서 만든 CheckBox 구현기를 적어보려고 한다!
처음에 CheckBox를 구현하려고 했을때는 간단해 보였지만, 고민해봐야 될 부분들이 꽤 있어서 생각보다 구현하는데 시간이 걸렸다.
먼저 구현된 Checkbox 컴포넌트 코드는 다음과 같다
text와 onChange, checked props를 받아온다.
text는 체크박스에 표현될 라벨, onChange는 체크박스의 변경을 제어하는 함수, checked는 체크 박스가 체크되었는지 여부를 알 수 있는 input태그의 checked 속성으로 boolean값을 가진다.
체크박스 컴포넌트 구현
import { InputHTMLAttributes } from "react";
import { CheckboxContainer, CheckboxInput, CheckboxText } from "./style";
interface CheckBoxProps extends InputHTMLAttributes<HTMLInputElement> {
text?: string;
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
type?: string;
}
export default function CheckBox({
id,
name,
text,
onChange,
type,
checked,
}: CheckBoxProps) {
return (
<CheckboxContainer>
<CheckboxInput
type="checkbox"
id={id}
name={name}
onChange={onChange}
$isCircle={type === "circle"}
checked={checked}
/>
<CheckboxText htmlFor={id}>{text}</CheckboxText>
</CheckboxContainer>
);
}
- 초기 상태가 빈 배열인 checkedListById 체크 목록을 만들고, 체크박스의 체크 목록 여부는 해당 항목의 id값으로 결정된다.
- 상품리스트 배열의 각 item의 id값을 이용해 체크박스를 제어할 수 있도록 구현했다.
- input[type=”checkbox”]의 checked속성을 이용하여 체크되었는지 확인하고 체크 여부를 통해 checkedListById 상태에 추가/제거하는 방식이다.
const [checkedListById, setCheckedListById] = useState<number[]>([]);
const checkedNum = checkedListById.length;
const handleCheckChange = (id: number) => {
const isChecked = checkedListById.includes(id);
if (isChecked) {
setCheckedListById((prev) => prev.filter((el) => el !== id));
} else {
setCheckedListById((prev) => [...prev, id]);
}
};
const handleAllCheck = ({
target: { checked },
}: {
target: { checked: boolean };
}) => {
if (checked) {
setCheckedListById(mockData.map((item: Item) => item.id));
} else {
setCheckedListById([]);
}
};
<CheckBox
text="전체선택"
onChange={handleAllCheck}
checked={checkedNum === mockData.length}
/>
{products.map((item) => (
<ProductItem key={item.id}>
<CheckBox
onChange={() => handleCheckChange(item.id)}
checked={checkedListById.includes(item.id)}
/>
...
</ProductItem>
))}