React中Bulma下拉菜单动态切换is-active状态的最优实现
实现方案
核心思路
完全不需要为每个菜单项单独创建useState,用一个状态变量记录当前激活菜单项的唯一标识(比如自定义ID)即可。渲染时对比每个项的标识与状态值,动态添加is-active类;同时保留下拉菜单的展开/收起状态管理,逻辑清晰且易维护。
完整代码实现
import React, { useState } from 'react'; const Dropdown = () => { // 控制下拉菜单的展开/收起状态 const [dropdownOpen, setDropdownOpen] = useState(false); // 记录当前激活的菜单项ID,初始值设为默认激活项的ID const [activeItemId, setActiveItemId] = useState('item-3'); // 切换下拉菜单显示状态 const toggleDropdown = (event) => { event.preventDefault(); setDropdownOpen(prev => !prev); }; // 统一处理菜单项点击:设置激活项,可选关闭下拉菜单 const handleItemClick = (itemId, event) => { event.preventDefault(); setActiveItemId(itemId); // 可选:点击菜单项后自动关闭下拉 setDropdownOpen(false); }; // 把菜单项数据抽成数组,避免重复编写JSX,后续修改更方便 const dropdownItems = [ { id: 'item-1', label: 'Dropdown item', href: '#' }, { id: 'item-2', label: 'Other dropdown item', href: '#' }, { id: 'item-3', label: 'Active dropdown item', href: '#' }, { id: 'item-4', label: 'Other dropdown item', href: '#' }, { id: 'divider', type: 'divider' }, { id: 'item-5', label: 'With a divider', href: '#' }, ]; return ( <div className={`dropdown ${dropdownOpen ? 'is-active' : ''}`}> <div className="dropdown-trigger"> <button className="button" aria-haspopup="true" aria-controls="dropdown-menu" onClick={toggleDropdown}> <span>Dropdown button</span> <span className="icon is-small"> <i className="fas fa-angle-down" aria-hidden="true"></i> </span> </button> </div> <div className="dropdown-menu" id="dropdown-menu" role="menu"> <div className="dropdown-content"> {dropdownItems.map(item => { // 渲染分隔线 if (item.type === 'divider') { return <hr key={item.id} className="dropdown-divider" />; } // 动态判断是否添加is-active类 const itemClass = `dropdown-item ${activeItemId === item.id ? 'is-active' : ''}`; return ( <a key={item.id} href={item.href} className={itemClass} onClick={(e) => handleItemClick(item.id, e)} > {item.label} </a> ); })} </div> </div> </div> ) } export default Dropdown;
关键细节说明
- 数据化管理菜单项:把所有下拉项(包括分隔线)整理成数组,后续新增、修改或删除菜单项只需调整数组,无需重复修改JSX结构,维护成本更低。
- 单个状态控制激活项:用
activeItemId记录当前激活项的唯一标识,点击菜单项时仅更新该状态,渲染时通过简单的条件判断动态添加is-active类,完全避免了多状态的冗余。 - 状态职责分离:将下拉展开/收起的状态(
dropdownOpen)与菜单项激活状态(activeItemId)分开管理,逻辑边界清晰,也能灵活控制交互(比如是否点击菜单项后关闭下拉)。 - 统一事件处理:用
handleItemClick函数处理所有菜单项的点击事件,减少重复代码,后续扩展逻辑(比如路由跳转)也只需修改这一个函数。
内容的提问来源于stack exchange,提问作者jbuddy_13
相关产品推荐
相关产品推荐

