select란
html에서 option태그를 자식 요소로 함께 사용하며 선택된 option의 value를 자신의 value로 가진다.
이 글에서는 select의 다음 내용에 대해 알아본다.
목표
select의 초기 dom 설정
select를 선택할 때 어떤 dom 프로퍼티가 변경되는가
select가 초기화되는 조건 알아보기
실험에 사용된 ui 주소
select의 초기 dom 설정 및 동작 방식
select태그는 자식인 option 태그 중에서 selceted 속성을 가진 녀석을 먼저 찾는다. (react의 경우에는 select의 props인 defaultValue나 value와 일치하는 option을 찾는다) 만약 찾는다면 그 option의 value와 index를 각각 select.value, select.selectedIndex에 저장한다. 조건에 맞는 option을 찾지 못했을 때는 가장 첫번째 자식인 option의 value와 index를 가져온다.
한편 select의 value로 선택된 option은 option.selected가 true로 할당된다.
(select는 내부의 자식 options을 참조할 때, 셀렉터를 사용하지 않아도 select.options로 참조가능하다.)
만약, select를 클릭하여 option을 변경하면 select의 value와 selectedIndex, option의 selected가 변경된다.
select와 option 프로퍼티 조작하기
이들의 프로퍼티를 조작하면 어떻게 될까.
select의 onChange 이벤트리스너에서 option.selectedIndex 값을 수동으로 바꾸면 option .value도 변경되고 화면에 선택된 값도 변경된다. option.value, option.selected도 변경된다. option.value를 변경할 때도 나머지 값들이 함께 변경된다. option.selected를 변경해도 select.value와 select.selectedIndex가 변경된다.
즉, 이 세 가지 프로퍼티는 읽기와 쓰기 전용 모두 사용가능하며 하나가 변경되면 다른 것도 함께 변경된다.
select의 초기화 조건, React에서 응용
만약 select가 선택한 옵션을 초기화하고 싶으면 어떻할까.
form이면 reset input을 설정하는 간단한 방법이 있지만, dom 조작으로 생각해보자.
selct 태그는 하위 option에 selected=true인 값을 찾아보고 없을 시 가장 첫번 째 자식인 option을 선택한다.
따라서 select.options를 forEach같은 메소드로 순회하며 selected=false 처리를 하면 초기화할 수 있다.
다른 방법은, select가 선택한 option 노드를 제거하는 것이다. 이 방법은 별 다른 에러가 발생하지 않으며 select를 초기화할수 있다. 이 방법은 react에서 select 컴포넌트를 마운트하거나 언마운트하는 방식으로 초기화할 때 사용할 수 있다.
약간 응용을 하면, select의 option들을 전부 변경해주면서도 select가 초기화되지 않게 할 수 있다.
react에서 여러 개의 select 컴포넌트를 만들 때면, 이 select들이 서로 연결되어 있을 때가 있다.
예컨대, selectA를 변경하면 selectB는 초기화되어야 하고 selectC는 초기화되지 말아햐 하는 방식이다.
이는 react의 id를 이용해서 가능하다. 초기화되어야할 select는 select나 하위 option의 id가 리렌더링 시에 변경되도록 고유값을 넣어주면 된다. 반면에 초기화되지 말아야할 select는 하위 option의 id가 리렌더링 시에 변경되지 않도록 고유하지 않은 값을 넣어주면 된다.
이 부분은 아래의 사용 예시를 보면 더 자세히 이해가 될 것이다.
정리
1. select는 값을 변경하는 특별한 메소드가 없다. 그래서 값을 변경할 때는 selectedIndex와 value를 사용할 수 있다.
둘 중 어느 게 낫냐면, select는 option에 존재하는 값만 선택가능하므로 selectedIndex가 나아보인다. option.index 속성으로 인덱스를 알아낸다면 selectedIndex에 할당하면 된다.
2. select를 초기화할 때는 form과 reset 태그를 사용해도 되지만, 상황이 그렇지 않을 때는 select의 selectedIndex 값을 변경하거나 select.options를 순회하며 selected=false 처리, 혹은 선택된 option 노드를 제거하면 된다.
3. 리엑트에서는 2의 방법과 id를 이용해서 초기화되어야할 select와 초기화되지 말아야할 select를 설정할 수 있다.
(사용 예시 참조)
사용 예시
아래 예시는 쿠폰, 직업, 헤어스타일의 셀렉터를 각각 가지고 있다. 쿠폰 셀렉터의 값에 따라 나머지 두 셀렉터의 옵션이 리렌더링되는데, 직업은 쿠폰 변경 시에 초기화되지 않지만, 헤어스타일은 초기화된다.
이는 id를 이용한 방식으로, 특정 셀렉터가 다른 셀렉터에 의존하여 초기화되어야 할때 유용하다.