Руководство о том, как создать собственное раскрывающееся меню в React.
Если вы хотите настроить элемент select в HTML, в большинстве случаев вы не сможете настроить его стиль. Вот почему я учу вас создавать собственные выпадающие списки в React.

Элемент выбора браузера по умолчанию в HTML отстой, серьезно! Вы бы поняли, если бы когда-нибудь пытались настроить его. Это было бы грязно! Итак, давайте создадим пользовательский компонент выбора в React с библиотекой styled-components.
Первым делом, первым 😁!
Настройте приложение React с помощью любого инструмента и установите пакет styled-components.
Создайте каталог components внутри папки src. И вперед, создайте подпапку внутри этой папки с именем Select. Создайте здесь файл index.js. Это файл, в котором мы будем писать код, необходимый для выбранного компонента. Этот компонент должен быть повторно использован в большинстве случаев, если функция будет почти как компонент выбора по умолчанию в HTML.
Начнем программировать ⌨️!
Хорошо, во-первых, создайте функциональный компонент реакции.
Совет: если вы используете VSCode, установите расширение Simple React Snippets. В нем есть несколько полезных фрагментов кода, которые автоматически сгенерируют для вас код!
Теперь введите rfc в файл и нажмите Enter! Вы получите функциональный компонент с именем функции в качестве имени файла.
Расширение URL: https://marketplace.visualstudio.com/items?itemName=burkeholland.simple-react-snippets
Назовите функцию Выбрать. Мы также принимаем некоторые реквизиты!
const Select = ({
label,
values,
onChange
}) => {
return (
<div>Select</div>
);
};
Теперь мы объявили наш реквизит! Теперь позвольте мне объяснить это!
- Метка: заполнитель для ввода
- Значения: допустимые значения
- onChange: обработчик события, который принимает параметр с переданным новым значением, они могут делать с ним что угодно!
Теперь, прежде чем перейти к функциональности, давайте создадим стили.
Стили для контейнера для него!
const SelectContainer = styled.div` position: relative; margin: 0; `;
Это стили для кнопки, внутри которой будет метка-заполнитель.
const SelectLabelButton = styled.button`
padding: 0.3rem 0.5rem;
min-width: 7rem;
font-size: 0.9rem;
font-weight: 500;
background-color: #fff;
border: none;
border-radius: 5px;
color: #111;
align-items: center;
justify-content: space-between;
border: 1px solid slategrey;
cursor: pointer;
box-shadow: 0 1px 4px 0 #ccc;
transition: 0.3s ease;
&:hover {
background-color: #eee;
}
`;
Теперь давайте создадим выпадающий элемент. Чтобы переключить видимость раскрывающегося списка, мы передаем свойство элементу с именем isVisible. Это установит видимость элемента, который будет скрыт. А также переключает максимальную высоту на 40px. Что поможет в создании эффекта анимации слайдов.
const DropdownStyle = styled.div`
position: absolute;
top: 0;
left: 0;
max-height: 40vmax;
min-width: 10rem;
padding: 0.4rem;
display: flex;
flex-direction: column;
border-radius: 5px;
background: #fafafa;
border: 1.5px solid slategrey;
transition: max-height 0.2s ease;
overflow: scroll;
${(p) =>
p.isVisible !== true &&
css`
max-height: 40px;
visibility: hidden;
`}
`;
Теперь давайте создадим элементы в раскрывающемся списке. Этот компонент примет свойство с именем active, которому требуется логическое значение. Если он активен, выпадающий элемент будет выделен.
const DropdownItem = styled.div`
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
display: flex;
align-items: center;
width: 90%;
margin: 0.15rem 0;
padding: 0.3rem 0.5rem;
font-size: 0.9rem;
font-weight: 400;
color: #333;
border-radius: 0.3rem;
cursor: pointer;
${(p) =>
p.active &&
css`
color: #166edc;
font-weight: 500;
`}
&:hover, :focus, :focus:hover {
background-color: #166edc;
color: #fafafa;
outline: none;
}
`;
Мы все готовы идти!
Теперь создайте хук useState() внутри функции.
const Select: (props) => {
const [currentValue, setCurrentValue] = useState('');
const [open, setOpen] = useState(false);
...
}
Далее мы добавим некоторые функции-обработчики для изменения состояний и вызовем обратный вызов onChange.
const handleOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
const handleValueChange = (value) => {
setCurrentValue(value);
};
const handleChange = (value) => {
handleValueChange(value);
// call method, if it exists
if (onChange) onChange(value);
// close, after all tasks are finished
handleClose();
};
Эти методы помогут нам изменить видимость раскрывающегося списка и изменить значение переменной currentValue.
Теперь мы также интегрируем эти методы с компонентами. Мы запускаем функцию handleOpen, когда нажимаем кнопку-заполнитель. Вызов функции handleClose монтируется внутри функции handleChange, поэтому при изменении значения раскрывающийся список автоматически закрывается.
return (
<SelectContainer>
<SelectLabelButton onClick={handleOpen}>
{currentValue !== "" ? currentValue : label}
</SelectLabelButton>
<DropdownStyle isVisible={open}>
{values.map((value, index) => (
<DropdownItem
onClick={() => handleChange(value)}
active={value === currentValue}
key={index}>
{value}
</DropdownItem>
))}
</DropdownStyle>
</SelectContainer>
);
Давайте воспользуемся этим компонентом:
import "./styles.css";
import Select from "./components/Select";
export default function App() {
let countries = ["USA", "Britain", "Germany", "India", "UAE", "Australia", "Switzerland"];
return (
<div className="App">
<Select label="Choose country" values={countries} onChange={(v) => console.log(v)} />
</div>
);
}
Теперь идем дальше и смотрим на предварительный просмотр в браузере.

Разве это не так просто и удивительно! И самое лучшее в этом компоненте — он ненадежен! ему не нужно передавать какое-либо состояние в качестве реквизита, и он также может позволить родительским компонентам получать значение с помощью обработчика onChange.
Итак, на сегодня все!
Надеюсь, у вас есть хорошее представление о том, как создавать собственные раскрывающиеся списки в React.
Надеюсь, сегодня вы узнали что-то новое!
Поддержите мою работу: Paypal 💰
Если вы хотите узнать больше обо мне, вот мое Дерево ссылок 🌲 .
Спасибо за прочтение ❤️!
Дальнейшее чтение
Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord. Заинтересованы в Взлом роста? Ознакомьтесь с разделом Схема.