REACT_체크박스 전체 선택,취소 만들기

JSkim·2022년 3월 14일

체크박스 여러개를 만들고 상호작용 해야할 때가 있다.
뭐...이용약관 같은거 만들 때?
아니면 쇼핑몰 마이 페이지에서 전체선택 기능 만들때 라던지..

암튼 그럴때 쓰는 코드를 정리해보자.

기본input 체크박스

<input name="체크박스이름" type="checkbox" onChange={(e)=>console.log(e.currentTarget.checked)}/>

여기까지하면 체크 할때마다 뭐 체크했는지 콘솔로그에 잘 찍혀 나온다.

이제 여러 체크박스를 만들고 컨트롤 해보자.

const [inputs, setInputs] = useState([
        {name:"one",level:1,checked:false},
        {name:"two",level:2,checked:false},
        {name:"three",level:2,checked:false},
        {name:"four",level:3,checked:false},
        {name:"five",level:3,checked:false},
        {name:"six",level:3,checked:false},
    ]);

나는 이름을 미리 지정해놓고 level개념을 뒀다. 상위 레벨이 하위레벨 컨트롤 하는
기능을 만들 예정.checked는 체크박스의 상태를 저장할 것임.

이제 저 state를 컨트롤 해보자.

JSX 부분

<div>
            <div>
                <input name="one" type={"checkbox"}
                       checked={inputs[0].checked} onChange={(e)=>{
                       checkboxHandler(e)}}/>
            </div>

            <div>

                <input name="two" type={"checkbox"} onChange={(e)=>{
                    checkboxHandler(e);
                }} checked={inputs[1].checked}
                />

                <input name="three" type={"checkbox"} onChange={(e)=>{
                    checkboxHandler(e);
                }}
                       checked={inputs[2].checked}
                />

            </div>
</div>

name: 나중에 filter사용할때 쓸 예정.
type: input 타입지정(우리는 체크박스 쓸 꺼니 checkbox라고 함)
onChange: 체크박스 변할때마다 벌어질 일들.
checked: 체크박스 상태가 어디를 따라갈 것인지.

그럼이제 checkboxHandler 함수를 살펴보자.

checkboxHandler

const checkboxHandler= (e)=>{
        if(e.target.name!=="one"){
            setInputs(inputs.map(
                (item)=>item.name===e.target.name
                    ?({...item, checked: e.currentTarget.checked})
                    :({...item})
            ))
            setClicker(clicker+1)
        }else{
            setInputs(inputs.map(
                (item)=>({...item, checked: e.currentTarget.checked})
            ))
        }
    }

input의 name택이 one(전체컨트롤체크박스)이라는 이름이 아니면(e.target.name에저장됨)
자신의 체크박스 상태를 확인하고 변경함.

하지만 name택이 one이면 one의 check값을 모든 박스에 지정해준다(전체선택기능)

그리고 추가적으로

const [clicker,setClicker]=useState(0);
    useEffect(()=>{
        const A = inputs.filter((item)=>item.level>1).length;
        const B = inputs.filter((item)=>item.level>1 && item.checked===true).length
        if(A===B){
            setInputs(inputs.map((item)=>item.name==="one"
                ?({...item,checked: true})
                :({...item})
            ))
        }else{
            setInputs(inputs.map((item)=>item.name==="one"
                ?({...item,checked: false})
                :({...item})
            ))
        }
    },[clicker])

useEffect에서 clicker라는 변수가 바뀔 때 마다 이런 동작을 하도록 설정했는데
A는 level1의 one 을 재외한 모든 박스들의 길이를 저장하고
B는 그안에서 true인 값을 저장한다.
두 값을 비교해서 만약 같으면 자동으로 one도 true가 되고
아니면 false가 됨.

간단하게 말해서 자신재외 모든 체크박스 체크하면 자동으로 체크되는것.
약관동의 같은 곳에서 많이 보이는 양식이다.

복붙해서 써도 좋고 조금 수정해서 써도 된다.
clicker사용하고 하는건 너무 대충만든거 같으니 나중에 수정해야지.

profile
제주도 프론트앤드 개발자의 개발 일기

0개의 댓글