<select>
Встроенный в браузер компонент <select> отвечает за рендер поля выбора с пунктами списка.
<select>
<option value="someOption">Пункт списка</option>
<option value="otherOption">Другой пункт списка</option>
</select>Справочник
<select>
Чтобы отобразить поле выбора, отрендерите встроенный в браузер компонент <select>.
<select>
<option value="someOption">Пункт списка</option>
<option value="otherOption">Другой пункт списка</option>
</select>Пропсы
<select> поддерживает все общие пропсы HTML-элементов.
Можно сделать поле выбора управляемым, передав проп value:
value: строка (или массив строк дляmultiple={true}). Управляет выбранным вариантом. Значение каждой строкиvalueсоответствует некоторому<option>, вложенному в<select>.
При передаче value, также необходимо передать обработчик onChange, который будет отвечать за обновление переданного значения.
Если не передать value, то <select> считается неуправляемым, и нужно использовать проп defaultValue:
defaultValue: строка (или массив строк дляmultiple={true}). Указывает значение по умолчанию.
Эти пропсы <select> актуальны для неуправляемых и управляемых полей выбора:
autoComplete: строка. Указывает одно из возможных поведений автозаполнения.autoFocus: булево значение. Еслиtrue, React установит фокус на элемент при монтировании.children:<select>принимает компоненты<option>,<optgroup>и<datalist>в качестве дочерних. Вы также можете передать свои собственные компоненты, но только в том случае, если в конечном итоге они рендерят один из вышеперечисленных компонентов. Если ваши компоненты рендерят теги<option>, то каждый отрендеренный<option>должен содержатьvalue.disabled: булево значение. Еслиtrue, то поле выбора не будет интерактивным и будет отображаться затемнённым.form: строка. Указываетidдля тега<form>, к которому относится поле выбора. Если значение не указано, то поле выбора будет относиться к ближайшей родительской форме.multiple: булево значение. Еслиtrue, то браузер будет поддерживать возможность множественного выбора.name: строка. Указывает имя для поля выбора, которое отправляется вместе с формой.onChange: функция обработчикаEvent. Требуется для управляемых полей выбора. Немедленно срабатывает, когда пользователь выбирает другой вариант. Ведёт себя как событиеinputв браузере.onChangeCapture: ВариантonChange, который срабатывает на этапе захвата события.onInput: функция обработчикаEvent. Немедленно срабатывает, когда пользователь меняет значение. По историческим причинам в React принято использовать вместо этогоonChange, который работает аналогичным образом.onInputCapture: ВариантonInput, который срабатывает на этапе захвата события.onInvalid: функция обработчикаEvent. Срабатывает в том случае, если введённые данные не прошли валидацию при отправке формы. В отличии от встроенного событияinvalid, в React событиеonInvalidвсплывает.onInvalidCapture: ВариантonInvalid, который срабатывает на этапе захвата события.required: булево значение. Еслиtrue, то необходимо указать значение для отправки формы.size: число. Дляmultiple={true}указывает количество изначально видимых элементов.
Предостережения
- В отличие от HTML, передача атрибута
selectedв<option>не поддерживается. Вместо этого используется<select defaultValue>для неуправляемого поля выбора и<select value>для управляемого. - Если поле выбора принимает проп
value, то оно будет считаться управляемым. - Поле выбора не может быть одновременно управляемым и неуправляемым.
- Поле выбора не может переключаться между управляемым и неуправляемым состоянием в течение своего жизненного цикла.
- Каждому управляемому полю выбора требуется обработчик событий
onChange, который синхронно обновляет его исходное состояние.
Применение
Отображение поля выбора с пунктами списка
Для отображения поля выбора используйте список компонентов <option> внутри тега <select>. Задайте value каждому элементу <option>, чтобы предоставить данные для отправки вместе с формой.
export default function FruitPicker() { return ( <label> Выберите фрукт: <select name="selectedFruit"> <option value="apple">Яблоко</option> <option value="banana">Банан</option> <option value="orange">Апельсин</option> </select> </label> ); }
Предоставление метки для поля выбора
Обычно каждый <select> размещают внутри тега <label>. Это сообщает браузеру, что данная метка связана с этим полем выбора. Когда пользователь нажмёт на метку, браузер автоматически установит фокус на поле выбора. Это также важно для доступности: когда пользовательский фокус будет на поле выбора, скринридер озвучит заголовок метки.
Если вы не можете вложить <select> в <label>, то свяжите их, передав некоторый ID в <select id> и <label htmlFor>. Чтобы избежать конфликтов между несколькими экземплярами одного компонента, сгенерируйте такой ID с помощью хука useId.
import { useId } from 'react'; export default function Form() { const vegetableSelectId = useId(); return ( <> <label> Выберите фрукт: <select name="selectedFruit"> <option value="apple">Яблоко</option> <option value="banana">Банан</option> <option value="orange">Апельсин</option> </select> </label> <hr /> <label htmlFor={vegetableSelectId}> Выберите овощ: </label> <select id={vegetableSelectId} name="selectedVegetable"> <option value="cucumber">Огурец</option> <option value="corn">Кукуруза</option> <option value="tomato">Помидор</option> </select> </> ); }
Предоставление значения по умолчанию
По умолчанию браузер выберет первый <option> в списке. Чтобы выбрать другой параметр по умолчанию, нужно передать value этого <option> в качестве defaultValue для элемента <select>.
export default function FruitPicker() { return ( <label> Выберите фрукт: <select name="selectedFruit" defaultValue="orange"> <option value="apple">Яблоко</option> <option value="banana">Банан</option> <option value="orange">Апельсин</option> </select> </label> ); }
Включение множественного выбора
Чтобы пользователь мог выбрать несколько вариантов, нужно передать multiple={true} в <select>. В этом случае, если также указать defaultValue для выбора вариантов по умолчанию, то это должен быть массив.
export default function FruitPicker() { return ( <label> Выберите несколько фруктов: <select name="selectedFruit" defaultValue={['orange', 'banana']} multiple={true} > <option value="apple">Яблоко</option> <option value="banana">Банан</option> <option value="orange">Апельсин</option> </select> </label> ); }
Считывание значения поля выбора при отправке формы
Оберните поле выбора в тег <form> с <button type="submit"> внутри. Это вызовет ваш обработчик событий <form onSubmit>. По умолчанию, браузер отправит данные формы на текущий URL и обновит страницу. Вы можете переопределить это поведение, вызвав e.preventDefault(). Считать данные формы можно с помощью new FormData(e.target).
export default function EditPost() { function handleSubmit(e) { // Предотвращаем перезагрузку страницы браузером e.preventDefault(); // Считываем данные формы const form = e.target; const formData = new FormData(form); // Вы можете передать formData напрямую, как тело запроса: fetch('/some-api', { method: form.method, body: formData }); // Вы можете сгенерировать из него URL, как это делает браузер по умолчанию: console.log(new URLSearchParams(formData).toString()); // Вы можете работать с ним, как с обычным объектом. const formJson = Object.fromEntries(formData.entries()); console.log(formJson); // (!) Не включает множественный выбор значений // Или вы можете получить массив пар ключ-значение. console.log([...formData.entries()]); } return ( <form method="post" onSubmit={handleSubmit}> <label> Выберите ваш любимый фрукт: <select name="selectedFruit" defaultValue="orange"> <option value="apple">Яблоко</option> <option value="banana">Банан</option> <option value="orange">Апельсин</option> </select> </label> <label> Выберите все ваши любимые овощи: <select name="selectedVegetables" multiple={true} defaultValue={['corn', 'tomato']} > <option value="cucumber">Огурец</option> <option value="corn">Кукуруза</option> <option value="tomato">Помидор</option> </select> </label> <hr /> <button type="reset">Сбросить</button> <button type="submit">Отправить</button> </form> ); }
Управление полем выбора при помощи переменной состояния
Поле выбора типа <select /> неуправляемое. Даже если передать значение по умолчанию типа <select defaultValue="orange" />, то ваш JSX будет указывать только на начально значение, а не на текущее.
Чтобы отрендерить управляемое поле выбора, передайте ему проп value. React принудит поле выбора всегда хранить переданное value. Обычно, управлять полем выбора можно при помощи переменной состояния:
function FruitPicker() {
const [selectedFruit, setSelectedFruit] = useState('orange'); // Объявляем переменную состояния...
// ...
return (
<select
value={selectedFruit} // ...сопоставляем value поля выбора с переменной состояния...
onChange={e => setSelectedFruit(e.target.value)} // ... и обновляем переменную состояния при любом изменении!
>
<option value="apple">Яблоко</option>
<option value="banana">Банан</option>
<option value="orange">Апельсин</option>
</select>
);
}Это полезно, если вы хотите повторно рендерить какую-то часть UI при каждом изменении значения в поле выбора.
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">Яблоко</option> <option value="banana">Банан</option> <option value="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">Огурец</option> <option value="corn">Кукуруза</option> <option value="tomato">Помидор</option> </select> </label> <hr /> <p>Ваш любимый фрукт: {selectedFruit}</p> <p>Ваши любимые овощи: {selectedVegs.join(', ')}</p> </> ); }