
만들어야 할 기능 - select 안 옵션 다중 선택과 선택 시 해당 옵션이 옆으로 배치되게 설정하기
다중 배치하는 방법은 select multiple={true} 로 설정하면 되지만
나처럼 옵션이 옆으로 나열되게 하려면 이 방식으로 디자인하기 복잡했다.
분명 이런 기능을 구현한 사람이 있을 것 같아서 자료를 뒤져봤지만 찾기 어려워서 다른 방법을 모색했다.
그것은 바로 리액트에서 제공하는 셀렉트 라이브러리이다.
ui가 간편하고 문서 정리가 잘 되어있는 편이라 이 방식을 선택하게 되었다.
npm install react-select
기본 구조는 이러하다.
import Select from 'react-select'
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' }
]
const MyComponent = () => (
<Select options={options} />
)
나는 languages라는 배열을 선언하고 안에는 백엔드와 통신하기 위해 value 값과 이름을 볼 수 있도록 name 값을 설정하였다.
import Select from 'react-select'
const languages = [
{ value: "KOREAN", name: "Korean" },
{ value: "JAPANESE", name: "Japanese" },
{ value: "CHINESE", name: "Chinese" },
{ value: "ENGLISH", name: "English" },
{ value: "VIETNAMESE", name: "Vietnamese" },
{ value: "SPANISH", name: "Spanish" },
{ value: "PORTUGUESE", name: "Portuguese" },
{ value: "ITALIAN", name: "Italian" }
];
<Select />
options - 선택할 항목 목록(필수 속성)
isMulti - 다중 선택 가능하게 함(생략 가능)
isClearable - X 선택 초기화 버튼 활성화
defaultValue - 기본 선택값 설정
value - 선택된 값을 제어
onChange - 값이 바뀔 시 호출되는 함수
placeholder - 아무 것도 선택되지 않았을 때 표시할 텍스트
isDisabled - 선택 불가 상태로 만들기
isSearchable - 검색 가능한 값, 기본값 true
name - 폼 제출 시 사용할 name 속성
<Select
className='select'
options={languages}
isMulti
getOptionLabel={(e) => e.name}
getOptionValue={(e) => e.value}
value={selectedLanguages}
onChange={setSelectedLanguages}
/>
여기서 getOptionLabel과 getOptionValue은 react-select를 커스텀 할 때 많이 사용되는 함수로
const options = [
{ value: 'apple', label: 'Apple' },
{ value: 'banana', label: 'Banana' }
];
const options = [
{ id: 'apple', name: '사과' },
{ id: 'banana', name: '바나나' }
];
기본 속성은 value와 label이지만
위처럼 내가 지정하고 싶은 키값이 다를 때 사용한다.
getOptionLabel={(e) => e.name} // 화면에 표시할 값
getOptionValue={(e) => e.value} // 실제로 사용할 값
import Select from 'react-select'
const [selectedLanguages,setSelectedLanguages] = useState([]); // 초기 배열 값 선언
const languages = [
{ value: "KOREAN", name: "Korean" },
{ value: "JAPANESE", name: "Japanese" },
{ value: "CHINESE", name: "Chinese" },
{ value: "ENGLISH", name: "English" },
{ value: "VIETNAMESE", name: "Vietnamese" },
{ value: "SPANISH", name: "Spanish" },
{ value: "PORTUGUESE", name: "Portuguese" },
{ value: "ITALIAN", name: "Italian" }
];
<label htmlFor='la'>
<span>Language <span style={{"display" : "inline"}}>*multiple options available</span></span>
<Select
className='select'
options={languages}
isMulti
getOptionLabel={(e) => e.name}
getOptionValue={(e) => e.value}
value={selectedLanguages} // 배열 초기값
onChange={setSelectedLanguages} // 변경된 값
/>
</label>
셀렉트 태그 다중선택 하는 로직을 구현하고 싶어 이리저리 찾아다녔는데 이렇게 간단한 방법이 있는 줄 모르고 몇시간을 서치하고 있었다. 알고보니 리액트에서 자주 사용하는 라이브러리인 것 같다. 진작 찾았으면 좋았겠지만 이것도 경험이라 생각해야겠다. 까먹지 않도록 잘 봐둬야겠다.