react实现dropdown
实现基础下拉菜单结构
使用 useState 控制下拉菜单的显示状态,通过按钮触发状态切换。基础结构包含按钮和下拉列表:
import { useState } from 'react';
function Dropdown() {
const [isOpen, setIsOpen] = useState(false);
return (
<div className="dropdown">
<button onClick={() => setIsOpen(!isOpen)}>Toggle Dropdown</button>
{isOpen && (
<ul className="dropdown-menu">
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
</ul>
)}
</div>
);
}
添加点击外部关闭功能
通过 useRef 和 useEffect 检测点击事件是否发生在下拉菜单外部,实现自动关闭:
import { useState, useRef, useEffect } from 'react';
function Dropdown() {
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef(null);
useEffect(() => {
const handleClickOutside = (event) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
setIsOpen(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
return (
<div ref={dropdownRef} className="dropdown">
{/* 其余代码同上 */}
</div>
);
}
支持动态选项与事件回调
通过 props 接收选项数据,并为选项添加点击回调函数:
function Dropdown({ options, onSelect }) {
const [isOpen, setIsOpen] = useState(false);
return (
<div className="dropdown">
<button onClick={() => setIsOpen(!isOpen)}>Select an option</button>
{isOpen && (
<ul className="dropdown-menu">
{options.map((option) => (
<li key={option.value} onClick={() => {
onSelect(option);
setIsOpen(false);
}}>
{option.label}
</li>
))}
</ul>
)}
</div>
);
}
// 使用示例
<Dropdown
options={[
{ value: '1', label: 'Option 1' },
{ value: '2', label: 'Option 2' }
]}
onSelect={(option) => console.log(option)}
/>
添加动画效果
使用 CSS 过渡或动画库(如 framer-motion)实现平滑展开/收起效果:
import { motion, AnimatePresence } from 'framer-motion';
function Dropdown() {
const [isOpen, setIsOpen] = useState(false);
return (
<div className="dropdown">
<button onClick={() => setIsOpen(!isOpen)}>Toggle Dropdown</button>
<AnimatePresence>
{isOpen && (
<motion.ul
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -10 }}
className="dropdown-menu"
>
{/* 选项内容 */}
</motion.ul>
)}
</AnimatePresence>
</div>
);
}
可复用组件优化
将下拉菜单封装为可复用的高阶组件,支持自定义触发器和菜单内容:
function Dropdown({ trigger, children }) {
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef(null);
// 添加点击外部关闭逻辑(参考前述代码)
return (
<div ref={dropdownRef} className="dropdown">
{React.cloneElement(trigger, { onClick: () => setIsOpen(!isOpen) })}
{isOpen && <div className="dropdown-content">{children}</div>}
</div>
);
}
// 使用示例
<Dropdown
trigger={<button>Custom Trigger</button>}
>
<div>Custom Dropdown Content</div>
</Dropdown>






