Работа с селектами в React

Давайте теперь займемся выпадающими списками select. Работа с ними также практически не отличается от работы с инпутами и чекбоксами.

Пусть у нас есть вот такой селект:

function App() { return <div> <select> <option>text1</option> <option>text2</option> <option>text3</option> <option>text4</option> </select> </div>; }

Давайте обеспечим его работу средствами React:

function App() { const [value, setValue] = useState(''); function handleChange(event) { setValue(event.target.value); } return <div> <select value={value} onChange={handleChange}> <option>text1</option> <option>text2</option> <option>text3</option> <option>text4</option> </select> <p> ваш выбор: {value} </p> </div>; }

Сделайте выпадающий список городов. Сделайте также абзац, в который будет выводиться выбор пользователя.

Пункты списка из массива

Пусть у нас есть массив с текстами пунктов выпадающего списка:

function App() { const texts = ['text1', 'text2', 'text3', 'text4']; const [value, setValue] = useState(''); return <div> ... </div>; }

Давайте сформируем наши теги option в цикле:

function App() { const texts = ['text1', 'text2', 'text3', 'text4']; const [value, setValue] = useState(''); const options = texts.map((text, index) => { return <option key={index}>{text}</option>; }); return <div> <select value={value} onChange={(event) => setValue(event.target.value)}> {options} </select> <p> ваш выбор: {value} </p> </div>; }

Пусть в массиве хранится список городов. Выведите с помощью цикла выпадающий список этих городов.

Атрибуты value

Пусть теперь у нас в тегах option есть атрибуты value:

function App() { return <div> <select> <option value="1">text1</option> <option value="2">text2</option> <option value="3">text3</option> </select> </div>; }

В таком случае из-за наличия атрибутов value в стейт будут попадать именно их значения, а не тексты тегов option. Можно убедится в этом, выведя результат выбора в абзац:

function App() { const [value, setValue] = useState(''); return <div> <select value={value} onChange={(event) => setValue(event.target.value)}> <option value="1">text1</option> <option value="2">text2</option> <option value="3">text3</option> </select> <p> ваш выбор: {value} </p> </div>; }

Разделить текст option и его значение может быть удобно: текст тега мы можем менять как нам угодно, при этом в нашем скрипте результат выбора будет обрабатываться по значению атрибута value, которые останется неизменным.

Смотрите пример:

function App() { const [value, setValue] = useState(''); return <div> <select value={value} onChange={event => setValue(event.target.value)}> <option value="1">text1</option> <option value="2">text2</option> <option value="3">text3</option> </select> <p> {value === '1' && 'вы выбрали первый пункт'} {value === '2' && 'вы выбрали второй пункт'} {value === '3' && 'вы выбрали третий пункт'} </p> </div>; }

Теперь, если мы изменим тексты оптионов, то работа скрипта не нарушится - ведь она привязана к значению атрибута value.

С помощью выпадающего списка предложите пользователю выбрать к какой возрастной группе он относится: от 0 до 12 лет, от 13 до 17, от 18 до 25, либо старше 25 лет.

Пункты из массива + атрибуты value

Пусть у нас опять пункты списка хранятся в массиве:

function App() { const texts = ['text1', 'text2', 'text3', 'text4']; const [value, setValue] = useState(''); ... }

Давайте сформируем с помощью этого массива теги option, добавив им в качестве атрибутов value ключи элементов массива:

function App() { const texts = ['text1', 'text2', 'text3', 'text4']; const [value, setValue] = useState(''); const options = texts.map((text, index) => { return <option key={index} value={index}>{text}</option>; }); ... }

Используя сформированные теги создадим выпадающий список:

return <div> <select value={value} onChange={event => setValue(event.target.value)}> {options} </select> </div>;

Выведем в абзац номер выбранного пункта:

return <div> <select value={value} onChange={event => setValue(event.target.value)}> {options} </select> <p> ваш выбор: {value} </p> </div>;

А теперь выведем текст выбранного пункта, используя его номер и массив с текстами:

return <div> <select value={value} onChange={event => setValue(event.target.value)}> {options} </select> <p> ваш выбор: {texts[value]} </p> </div>;

Соберем все вместе и получим следующий код:

function App() { const texts = ['text1', 'text2', 'text3', 'text4']; const [value, setValue] = useState(''); const options = texts.map((text, index) => { return <option key={index} value={index}>{text}</option>; }); return <div> <select value={value} onChange={event => setValue(event.target.value)}> {options} </select> <p> ваш выбор: {texts[value]} </p> </div>; }