이번 글에서는 React에서 Select Box 컴포넌트를 만드는 방법을 알아보도록 하겠습니다.
HTML에서 Select Box 구성요소
기본적으로 select box 태그의 경우, 내부에 여러 option을 option 태그로 넣는 구조로 되어 있습니다. 이를 이제 React로 옮겨 보도록 하겠습니다.
React에서 Select Box 만들기
react에서는 children 컴포넌트(위 코드에서는 select 아래에 있는 option 컴포넌트)에는 반드시 key props가 있어야 하므로, key props를 추가하여 주었습니다.
위와 같이 코드를 변경하고, 다시 실행하면 기존과 같이 select box
가 렌더링 되는 것을 알 수 있습니다.
select box 옵션을 props로 받기
기존의 코드는 select box
의 옵션들을 하드코딩하여 넣어두었는데, 이제는 option
을 props
를 통해서 받아보도록 하겠습니다.
SelectBox
컴포넌트에서 options
를 props
로 받아서 SelectBox
컴포넌트 내부에서 map
을 통해서 option
컴포넌트를 하나씩 만들어 주었습니다.
selectBox default value 추가하기
selectBox
가 렌더링될 때 최초에 렌더링될 default value
를 설정해 보도록 하겠습니다.
SelectBox 컴포넌트에서 defaultValue props를 받습니다.
그리고 option을 렌더링할 때 defaultValue={props.defaultValue === option.value}
를 통해서 props에서 받은 defaultValue와 option의 value를 확인하여 selected props의 값을 변경하여 줍니다.
실행해보면 위와 같이 바나나가 최초 option으로 렌더링 되는 것을 알 수 있습니다.
select box handler 추가하기
select box도 button 컴포넌트처럼 onChange event를 통해서 선택된 값에 접근할 수 있습니다.
선택된 값은 e.target.value 안에 포함되어 있으며, 위와 같이 선택할 때마다 선택된 옵션의 value 값이 찍힌 것을 알 수 있습니다.
Select Box CSS 커스텀하기
select box의 사용방법을 알아보았으니, styled-components를 통해서 CSS를 변경해 보도록 하겠습니다.
우선 styled-components를 설치하도록 하겠습니다.
yarn add styled-components
그리고 아래와 같이 코드를 변경해 줍니다.
styled-components에서 styled를 import하고 우리만의 Select 컴포넌트를 생성해 줍니다. 위 코드를 보면, Select 컴포넌트 내부의 style로 selectbox를 focus 시에 border를 빨간색으로 변경하였습니다.
실행해 보면 위와 같이 style이 변경된 것을 알 수 있습니다. 이외에도 다양한 스타일을 추가할 수 있습니다.
Select Box 아이콘 변경하기
select box의 경우, 각 브라우저 별로 default Icon이 정해져 있습니다. 이제는 이 Icon을 우리가 원하는 icon으로 변경해 보도록 하겠습니다.
위와 같이 style을 추가하면 아래처럼 방향 화살표가 없어진 것을 알 수 있습니다.
이제 이 곳에 우리의 아이콘(아래 방향 삼각형 아이콘)을 넣어 보도록 하겠습니다.
변경된 코드 내용
- Select Box 내에서 display: flex를 사용하기 위해 SelectBoxWrapper 컴포넌트를 추가
- svg 태그에 스타일을 추가하기 위해 IconSVG 컴포넌트를 추가 (위치 설정, 아이콘 크기, 정렬)
위와 같이 코드를 변경하고 실행해 보도록 하겠습니다.
위 화면처럼 우리가 원하는 대로 아이콘이 변경된 것을 알 수 있습니다.
이로써 간단하게 Select Box 컴포넌트를 만드는 방법을 알아 보았습니다. 이외에도 React에서는 Select Box를 쉽게 만들 수 있는 라이브러리가 존재합니다. (링크)
직접 커스터마이징하여 쓰기에는 시간이 부족하다고 생각되시면 위 라이브러리를 써보시는 것도 추천드립니다.
전체 코드 살펴보기
- github에서 전체 코드 보기 (링크)
이 블로그 글은 Code Pot, 리액트 챌린지의 과제로 작성되었습니다.
Code Pot, 리액트 챌린지가 궁금하다면? ⇒ 링크