Reference
<select>
내장 브라우저 <select>
컴포넌트는 옵션이 있는 셀렉트 박스를 렌더링할 수 있게 해줍니다.
<select>
<option value="someOption">Some option</option>
<option value="otherOption">Other option</option>
</select>
아래에서 더 많은 예시를 확인할 수 있습니다.
Props
<select>
는 모든 공통 엘리먼트 props를 지원합니다.
value
: string 또는 string 배열(multiple={true}일 때). 어떤 옵션이 선택되는지 제어합니다. 각 값은 내부<option>
의 value와 일치해야 합니다. value를 전달하면 반드시 onChange 핸들러도 함께 전달해야 합니다.defaultValue
: string 또는 string 배열(multiple={true}일 때). 비제어 셀렉트 박스의 초기 선택값을 지정합니다.autoComplete
: string. 자동완성 동작 지정autoFocus
: boolean. true면 마운트 시 자동 포커스children
:<select>
는disabled
: boolean. true면 비활성화 및 흐리게 표시form
: string. 이 select가 속한multiple
: boolean. true면 다중 선택 허용name
: string. 폼 제출 시 함께 전송되는 이름onChange
: 이벤트 핸들러. 제어형 select에서 필수. 사용자가 옵션을 변경할 때마다 즉시 호출onInput
,onInvalid
: 각각 값 변경/유효성 검사 실패 시 호출required
: boolean. true면 값이 반드시 필요size
: number. multiple={true}일 때, 기본으로 보이는 항목 개수 지정
Caveats(주의사항)
- HTML과 달리,
<option>
에 selected 속성을 전달하는 것은 지원하지 않습니다. 비제어 select에는 - select에 value prop이 있으면 제어형으로 간주됩니다.
- select는 제어형/비제어형을 동시에 사용할 수 없습니다.
- select는 라이프사이클 동안 제어형/비제어형을 오갈 수 없습니다.
- 제어형 select에는 반드시 onChange 핸들러가 필요하며, state를 동기적으로 업데이트해야 합니다.
사용법
옵션이 있는 select 박스 표시
export default function FruitPicker() {
return (
<label>
과일 선택:
<select name="selectedFruit">
<option value="apple">Apple</option>
<option value="banana">Banana</option>
<option value="orange">Orange</option>
</select>
</label>
);
}
select 박스에 label 제공
일반적으로 <select>
는
import { useId } from 'react';
export default function Form() {
const vegetableSelectId = useId();
return (
<>
<label>
과일 선택:
<select name="selectedFruit">
<option value="apple">Apple</option>
<option value="banana">Banana</option>
<option value="orange">Orange</option>
</select>
</label>
<hr />
<label htmlFor={vegetableSelectId}>
채소 선택:
</label>
<select id={vegetableSelectId} name="selectedVegetable">
<option value="cucumber">Cucumber</option>
<option value="corn">Corn</option>
<option value="tomato">Tomato</option>
</select>
</>
);
}
기본 선택 옵션 지정
기본적으로 첫 번째
export default function FruitPicker() {
return (
<label>
과일 선택:
<select name="selectedFruit" defaultValue="orange">
<option value="apple">Apple</option>
<option value="banana">Banana</option>
<option value="orange">Orange</option>
</select>
</label>
);
}
⚠️ HTML과 달리,
다중 선택 허용
multiple={true}를 전달하면 여러 옵션을 선택할 수 있습니다. 이때 defaultValue도 배열로 지정해야 합니다.
export default function FruitPicker() {
return (
<label>
여러 과일 선택:
<select
name="selectedFruit"
defaultValue={['orange', 'banana']}
multiple={true}
>
<option value="apple">Apple</option>
<option value="banana">Banana</option>
<option value="orange">Orange</option>
</select>
</label>
);
}
폼 제출 시 select 값 읽기
form 태그로 감싸고
export default function EditPost() {
function handleSubmit(e) {
e.preventDefault();
const form = e.target;
const formData = new FormData(form);
// fetch 등으로 전송 가능
console.log(new URLSearchParams(formData).toString());
const formJson = Object.fromEntries(formData.entries());
console.log(formJson); // multiple select 값은 포함되지 않음
console.log([...formData.entries()]);
}
return (
<form method="post" onSubmit={handleSubmit}>
<label>
좋아하는 과일:
<select name="selectedFruit" defaultValue="orange">
<option value="apple">Apple</option>
<option value="banana">Banana</option>
<option value="orange">Orange</option>
</select>
</label>
<label>
좋아하는 채소 모두:
<select
name="selectedVegetables"
multiple={true}
defaultValue={['corn', 'tomato']}
>
<option value="cucumber">Cucumber</option>
<option value="corn">Corn</option>
<option value="tomato">Tomato</option>
</select>
</label>
<hr />
<button type="reset">초기화</button>
<button type="submit">제출</button>
</form>
);
}
💡 select에 name을 지정하면, 폼 데이터에서 해당 name이 key로 사용됩니다. multiple select는 선택된 값마다 별도의 name-value 쌍이 생성됩니다.
⚠️ form 내의 어떤
state로 select 제어 (제어형 select)
select에 value prop을 전달하면 제어형이 됩니다. state 변수로 value를 관리하고, onChange에서 state를 동기적으로 업데이트해야 합니다.
import { useState } from 'react';
export default function FruitPicker() {
const [selectedFruit, setSelectedFruit] = useState('orange');
const [selectedVegs, setSelectedVegs] = useState(['corn', 'tomato']);
return (
<>
<label>
과일 선택:
<select
value={selectedFruit}
onChange={e => setSelectedFruit(e.target.value)}
>
<option value="apple">Apple</option>
<option value="banana">Banana</option>
<option value="orange">Orange</option>
</select>
</label>
<hr />
<label>
좋아하는 채소 모두:
<select
multiple={true}
value={selectedVegs}
onChange={e => {
const options = [...e.target.selectedOptions];
const values = options.map(option => option.value);
setSelectedVegs(values);
}}
>
<option value="cucumber">Cucumber</option>
<option value="corn">Corn</option>
<option value="tomato">Tomato</option>
</select>
</label>
<hr />
<p>선택한 과일: {selectedFruit}</p>
<p>선택한 채소: {selectedVegs.join(', ')}</p>
</>
);
}
⚠️ value를 전달했지만 onChange를 전달하지 않으면 옵션을 선택할 수 없습니다. 반드시 state를 동기적으로 업데이트하세요.
⚠️ HTML과 달리,
반응형