개발/🔵 React-TypeScript

전체선택 구현하기

비니_ 2025. 9. 16. 10:21
728x90

 

 

CheckboxList 컴포넌트

"use client";

import { useEffect, useState } from "react";

interface Option{
    id: number;
    label: string;
}

interface CheckProps{
    options?: string[];
}

const CheckboxList = ({
    options = ['Option1', 'Option2', 'Option3'],
}: CheckProps) => {
    const optionList: Option[] = options.map((label, index) => ({
        id: index  + 1,
        label,
    }));

    const [checkedList, setCheckedList] = useState<number[]>([]);

    const toggleOption = (id:number) => {
        setCheckedList(prev =>
            prev.includes(id)
                ? prev.filter(v => v !== id)
                : [...prev, id]
        );
    };

    const allChecked = checkedList.length === optionList.length;

    useEffect(() => {
        console.log('consolelog==============================');
        console.log(checkedList);
    }, [checkedList]);

    // 1. 옵션 체크 값을 넣는 박스
    // 2. 그 박스에서 값을 비교 하여 전체선택, 전체해제
    // 3. 전체선택, 전체해제 텍스트 변경

    const toggleAll = () => {
        if(allChecked){
            setCheckedList([]); // 전체해제
        }else{
            setCheckedList(optionList.map((option) => option.id)); // 전체선택
        }
    }

    return(
        <div>
            {/* 전체선택 박스 */}
            <label>
                <input
                    type='checkbox'
                    checked={allChecked}
                    onChange={toggleAll}
                />
                전체선택
            </label>
            {/* 각 체크박스 */}
            {optionList.map(v => (
                <label key={v.id}>
                    <input
                        type='checkbox'
                        checked={checkedList.includes(v.id)} // 체크시 checked
                        onChange={() => toggleOption(v.id)}
                    />
                    {v.label}
                </label>
            ))}
        </div>
    )
}

export default CheckboxList;

 

✔ useEffect와 useState를 쓰기 위해서는 상단에 "use client"를 기입

✔ options props는 오류를 막기 위해 기본 값으로  넣어 둠

✔ interface가 2개로 나뉜 이유

=> CheckProps: 컴포넌트 외부 인터페이스(전달 받는 데이터 형태)

=> Option: 컴포넌트 내부 데이터 형태(상태 관리용)

 

💻  const [checkedList, setCheckedList] = useState<number[]>([]);

=> 체크된 옵션 id를 저장하는 상태(초기값은 빈 배열)

 

💻  const toggleOption = (id:number) => {
    setCheckedList(prev =>
        prev.includes(id)
            ? prev.filter(v => v !== id)  // ✔ 이미 체크 되어 있으면 제거(filter 사용)
            : [...prev, id]  // ✔ 체크 안되어 있으면 추가
    );
};

 

<Toggle
    isOn={isOn}
    isOnFalse='체크 옵션 나옴'
    isOnTrue='체크 옵션 숨김'
    onToggle={() => setIsOn(prev => !prev)}
/>
{isOn && (
    <Checkbox
    	options={['option', 'option2']}
	/>
)}

 

 

728x90