기존의 로직
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const checkboxes = document.getElementsByName('price') as NodeListOf<HTMLInputElement>;
for (let i = 0; i < checkboxes.length; i++) {
if (checkboxes[i] !== e.target) {
checkboxes[i].checked = false;
}
}
};
document.getElementsByName
코드 때문!NodeListOf<HTMLInputElement>
라는 것을 개발자가 알려주지 않으면 모르는 것이다.Ref를 사용한 로직
const [priceRefs, setPriceRefs] = useState<React.RefObject<HTMLInputElement>[]>([]);
const priceFilterList = ['만원 이하', '1~2만원', '2~4만원', '4만원 이상'];
useEffect(() => {
setPriceRefs(
Array(4)
.fill(0)
.map(() => createRef())
);
}, []);
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (!priceRefs) return;
for (let i = 0; i < priceRefs.length; i++) {
if (priceRefs[i].current !== null && priceRefs[i].current !== e.target) {
priceRefs[i].current!.checked = false;
}
}
};
...
return (
...
{priceFilterList.map((priceFilter, index) => (
<Checkbox
priceRef={priceRefs[index]}
handler={handlePrice}
handleChange={handleChange}
value={priceFilter}
/>
))}
)
useEffect(() => {
const initRefs = Array(4)
.fill(0)
.map(() => createRef());
setPriceRefs(initRefs);
}, []);
useState와 index를 활용하는 방법
const [checkedIndex, setCheckedIndex] = useState<number | null>(null);
const priceFilterList = ['만원 이하', '1~2만원', '2~4만원', '4만원 이상'];
const categoryFilterList = ['음식점', '미용업', '세탁업', '숙박업', '기타'];
const handleChange = (index: number) => {
setCheckedIndex(index);
};
...
return (
...
{priceFilterList.map((priceFilter, index) => (
<Checkbox
index={index}
checked={checkedIndex === index}
handler={handlePrice}
handleChange={handleChange}
value={priceFilter}
/>
))}
)