react下拉菜单实现
实现React下拉菜单的方法
使用原生HTML和React状态控制
通过React的useState钩子管理下拉菜单的显示状态,结合HTML的select标签或自定义div结构实现。
import { useState } from 'react';
function Dropdown() {
const [isOpen, setIsOpen] = useState(false);
const [selectedOption, setSelectedOption] = useState(null);
const options = ['Option 1', 'Option 2', 'Option 3'];
return (
<div className="dropdown">
<button onClick={() => setIsOpen(!isOpen)}>
{selectedOption || 'Select an option'}
</button>
{isOpen && (
<ul className="dropdown-list">
{options.map((option) => (
<li key={option} onClick={() => {
setSelectedOption(option);
setIsOpen(false);
}}>
{option}
</li>
))}
</ul>
)}
</div>
);
}
使用第三方库(如react-select)
对于更复杂的需求,可以使用成熟的第三方库如react-select,提供丰富的功能和样式定制。

import Select from 'react-select';
const options = [
{ value: 'option1', label: 'Option 1' },
{ value: 'option2', label: 'Option 2' },
{ value: 'option3', label: 'Option 3' }
];
function App() {
return (
<Select
options={options}
onChange={(selected) => console.log(selected)}
/>
);
}
添加动画效果
通过CSS过渡或动画库(如Framer Motion)增强用户体验。

import { motion, AnimatePresence } from 'framer-motion';
function AnimatedDropdown() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(!isOpen)}>Toggle</button>
<AnimatePresence>
{isOpen && (
<motion.ul
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
>
<li>Item 1</li>
<li>Item 2</li>
</motion.ul>
)}
</AnimatePresence>
</div>
);
}
可访问性优化
遵循WAI-ARIA标准,确保屏幕阅读器可以正确识别下拉组件。
<div role="combobox" aria-expanded={isOpen} aria-haspopup="listbox">
<button
aria-controls="dropdown-list"
onClick={() => setIsOpen(!isOpen)}
>
{selectedOption || 'Select'}
</button>
<ul id="dropdown-list" role="listbox">
{options.map((option) => (
<li
role="option"
key={option}
aria-selected={selectedOption === option}
>
{option}
</li>
))}
</ul>
</div>
样式定制
通过CSS模块或Styled-components实现个性化样式。
import styled from 'styled-components';
const StyledDropdown = styled.div`
position: relative;
width: 200px;
`;
const DropdownButton = styled.button`
padding: 8px 16px;
width: 100%;
`;
function StyledComponentDropdown() {
// 实现逻辑与原生示例相同
return <StyledDropdown>{/* ... */}</StyledDropdown>;
}






