오늘은 체크박스 만드는 과정을 알아보려고 한다.
누구든 한 번 보고 쉽게 이해할 수 있도록 차근차근..
한 번 써보자.
기준은 React로 만들었다.
복잡하지 않게 기초로!
CheckBox 만들기
정말정말 기본부터 순차적으로 설명할 것이다.
1. 데이터 만들기
우선 데이터를 가짜로 만들어 주었다.
원래는 서버에서 받을텐데..
일단 데이터에 들어있는 것은 id와 title 값만 있다.
2. 데이터 render하기
위에서 만든 데이터를 react Render부분에 만들어주었다.
만들 때는 전체선택은 하나 따로 만들어주었고
data.map을 통해 데이터를 한 번에 만들었다.
이때 각각의 checkbox에 id={data.id}로 고유의 id를 만들어 주었다.
span을 통해 title을 달아주었다.
key는 react에서 map을 사용할 때 각각의 고유의 key값이 필요해서 만들어주었다.
그러면 브라우저에서 열어보면 현재 이런 상태이다.
3. 체크된 항목을 확인할 수 있는 배열 하나 만들기
누가 체크 됐는지 알려면 체크된 항목들을 저장할 수 있는 State가 하나 필요하다.
그래서 만들었다.
4. 개별체크 함수 만들기
먼저 개별 체크 함수를 만들었다.
들어오는 인자는 e(event)하나만 있다.
먼저 input checkbox에는 event.target.checked라는 속성이 있다.
이 속성은 check를 할 경우 true, check를 풀면 false값을 반환한다.
그래서 먼저 우리가 누른 체크박스를 check 상태로 만들면 true값이다.
true값일 때 nowCheck 라는 배열을 하나 선언 했다.
얘는 실제로 check된 input의 id를 저장하는 녀석이다.
…checkItmes -> …연산자를 써야지 기존에 check된 정보를 저장한 상태로
새로운 값을 넣을 수 있다.
그리고 nowCheck를 checkItems 배열에 넣어줬다.
바로 setCheckItems에 넣은 것이 아니라 nowCheck에 넣어준 이유는
console.log()를 할 때 바로 확인하기 위함이다.
만약 바로 setCheckItems([…checkItems], e.target.id)를 할 경우 한 박자 늦게 찍힌다.
그 이유는 checkItems에 값이 들어가기 전에 console.log()로 값을 확인하기 때문이다.
else 부분에는 check를 풀었을 때는 filter를 이용해서 같은 id가 배열에 이미 있을 경우,
해당 값을 삭제하는 로직이다.
그리고 위에 만든 개별체크 함수를 render부분에 onChange로 넣어줬다.
그냥 onChange={handleCheck}를 할 경우 자동으로 인자에 event 속성이 들어가게 된다.
그리고 checked 속성을 넣어줬다.
checkItmes.includes 기능을 이용하여 해당 아이디가 배열에 없으면 true로 만들어서 체크 상태,
아니면 false상태로 만든다.
잘 작동한다.
5. 전체 체크 함수 만들기
전체 체크 함수는 체크를 할 경우 data에 있는 모든 id를 checkItems 배열에 넣어주게 된다.
해당 기능은 map을 통해 넣어주었다.
여기서 nowCheck에 먼저 넣고 setCheckItems()에 한 번 더 넣어서 굳이 2번을 넣어준 이유는
console.log()에서 값을 바로 확인하기 위함이다.
위에서도 설명했듯이 console.log(checkItems)하면 한 박자 늦게 찍히게 된다.
else 부분에는 전체 선택을 모두 해제할 때는 배열을 그냥 비워준다.
render부분에는 이렇게 들어간다.
전체 선택은 아래 항목들이 모두 체크될 때만 check, 아니면 check가 풀린다.
그래서 checked={}조건에는 체크된 항목들이 저장된 checkItems와 data의 길이를 비교해
true, false로 만들어 준다.
잘 작동된다.
만들 때 생긴 이슈
만들면서 몇 가지 이슈가 생겼다.
1. onClick이 아니라 onChange
처음에는 체크박스니까 클릭할 때 함수가 실행되기 위해 onClick에 함수를 넣었다.
그러니까 브라우저 상에서는 잘 작동했지만 console창에는 어떤 오류가 떴다.
checked라는 속성은 상태에 따라 계속 변한다.
그래서 onClick과 checked를 같이 주게 되면 해당 메시지가 나온다.
그래서 꼭 onChange를 통해 checked 속성을 바꿔주어야 했다.
2. id의 type이 Number / String
처음 가짜 data를 만들 때는 id :1, id:2
이런 식으로 Number 타입의 값을 넣어주고,
해당 값을 id={data.id}로 넣었다.
그랬더니 type문제가 발생했다.
data.id => Number
id={data.id} => String
이렇게 id로 만든 값은 String으로 반환이 됐다.
그래서 함수에서 강제로 Number 타입으로 변환하거나 String 타입으로 변환시켜
타입을 동일하게 만들어 주어야 했다.
해당 과정이 너무 번거롭고 오류를 일으킬 수 있어서
그냥 id:”1”로 하여 애초에 String으로 만들어 주었다.
3. 바로 setCheckItems가 아니라 nowCheck변수에 먼저 담고 setCheckItmes(nowCheck)
이렇게 한 이유는 console.log()에서 값을 바로 확인하기 위함이다.
우리는 보통 setCheckItems([…checkItems, e.target.id])
이렇게 바로 넣고
console.log(checkItems)를 할 것이다.
그렇게 되면 setCheckItems함수를 통해 checkItems에 데이터가 제대로 들어가기 전에
console.log()로 확인하게 되어 한 박자 느리게 값을 확인한다.
setState함수에 넣은 값은 다시 랜더링을 할 때 값을 제대로 확인할 수 있기에 생기는 문제이다.
그래서 nowCheck라는 변수를 만들고
setCheckItems(nowCheck)로 넣은 후
console.log(nowCheck)로 확인했다.
어차피 setCheckItems에 들어가는 값은 똑같지만
바로 확인할 수 있다는 점이 다르다.
끝!!