Руководство о том, как создать собственное раскрывающееся меню в 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. Заинтересованы в Взлом роста? Ознакомьтесь с разделом Схема.