Next.js中如何通过点击函数实现手风琴菜单三种状态管理
实现Next.js手风琴菜单的三种状态
当前代码仅通过单个状态跟踪打开的菜单,无法区分“最近关闭”的状态。需要新增状态记录最近关闭的菜单ID,通过判断菜单ID与两个状态的关系来应用对应的CSS类。
修改后的组件代码
export default function Menu() { const context = useContext(navItems); const listItems = context.listItems; // 跟踪当前打开的菜单ID和最近关闭的菜单ID const [openItemId, setOpenItemId] = useState(null); const [recentClosedItemId, setRecentClosedItemId] = useState(null); function selectItemHandler(id) { if (id === openItemId) { // 点击已打开的菜单,关闭它并标记为最近关闭 setOpenItemId(null); setRecentClosedItemId(id); } else { // 点击未打开的菜单,打开它并清除最近关闭标记 setOpenItemId(id); setRecentClosedItemId(null); } } return ( <> {listItems.map((menuItems) => { let itemClass; if (menuItems.id === openItemId) { itemClass = styles.mainLi_open; } else if (menuItems.id === recentClosedItemId) { itemClass = styles.mainLi_recentOpen; } else { itemClass = styles.mainLi_default; } return ( <ul key={menuItems.id} className={`${styles.list}`}> <li id={menuItems.id} className={`${styles.mainLi} ${itemClass}`} onClick={() => selectItemHandler(menuItems.id)} > <div className={`${styles.options}`}> <span>{menuItems.icon}</span> <span>{menuItems.title}</span> <span> <IoIosArrowDown /> </span> </div> <ul className={styles.subMenu}> {menuItems.subItems.map((subitem) => ( <li key={subitem.id}> <Link href={subitem.path}>{subitem.title}</Link> </li> ))} </ul> </li> </ul> ); })} </> ); }
关键逻辑说明
- 新增
recentClosedItemId状态,专门记录刚刚被关闭的菜单ID - 点击事件处理:
- 若点击的是当前打开的菜单,关闭它并将其ID存入
recentClosedItemId - 若点击的是其他菜单,打开目标菜单并清空
recentClosedItemId(让之前的菜单回到默认状态)
- 若点击的是当前打开的菜单,关闭它并将其ID存入
- 类名判断:优先匹配打开状态,其次匹配最近关闭状态,最后使用默认状态
CSS样式说明
你已定义的三种状态样式无需修改,当前逻辑会自动根据状态切换对应的CSS类:
.mainLi_default:菜单未被点击过的默认状态.mainLi_open:首次点击后打开的状态.mainLi_recentOpen:点击已打开的菜单关闭后的状态
内容的提问来源于stack exchange,提问作者Majid Hatamimaleki
相关产品推荐
相关产品推荐

