You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextUI下拉菜单:已有菜单展开时实现单击打开新菜单

解决NextUI下拉菜单切换需两次点击的问题

问题原因

手动控制Dropdown的isOpen状态时,原有handleDropdownClick的逻辑仅处理当前下拉的切换,未正确处理点击其他下拉时直接替换活跃状态的场景。当已有下拉展开时,第一次点击新下拉会触发状态切换(关闭旧的),但Dropdown组件内部状态与外部useState不同步,导致需要第二次点击才能打开新下拉。

修复方案

修改状态更新逻辑,点击新下拉菜单时直接将activeDropdown设为当前索引;点击已展开的下拉则关闭它。同时利用onOpenChange传入的isOpen参数同步状态,避免内外状态不一致。

修改后的完整代码:

'use client'

import React, { useState } from 'react'
import {
  Navbar,
  NavbarContent,
  NavbarItem,
  Link,
  DropdownMenu,
  DropdownItem,
  Dropdown,
  DropdownTrigger,
  Button
} from '@nextui-org/react'

export function NavbarFooter() {
  const items = [
    {
      title: 'Dropdown 1',
      dropdown: [
        { title: 'Subitem 1', path: '/' },
        { title: 'Subitem 2', path: '/' }
      ]
    },
    {
      title: 'Dropdown 2',
      dropdown: [
        { title: 'Subitem 1', path: '/' },
        { title: 'Subitem 2', path: '/' }
      ]
    },
    { title: 'Item 3', path: '/' }
  ]

  const [activeDropdown, setActiveDropdown] = useState<null | number>(null)

  const handleDropdownToggle = (index: number, isOpen: boolean) => {
    // 点击已展开的下拉则关闭,否则切换到当前下拉
    setActiveDropdown(isOpen ? index : (activeDropdown === index ? null : index))
  }

  return (
    <Navbar
      className="top-[4rem] w-full bg-[#BC9A22] px-0 md:h-[2.8rem]"
      height="0.8rem"
      maxWidth="2xl"
    >
      <NavbarContent justify="end" className="">
        {items.map((item, index) =>
          item.dropdown ? (
            <NavbarItem key={`${item.title}-${index}`}>
              <Dropdown
                isOpen={activeDropdown === index}
                onOpenChange={(isOpen) => handleDropdownToggle(index, isOpen)}
              >
                <DropdownTrigger>
                  <Button>
                    {item.title}
                    {activeDropdown === index ? ' ▲' : ' ▼'}
                  </Button>
                </DropdownTrigger>

                <DropdownMenu>
                  {item.dropdown.map((subItem, subIndex) => (
                    <DropdownItem key={subIndex}>
                      <Link href={subItem.path}>{subItem.title}</Link>
                    </DropdownItem>
                  ))}
                </DropdownMenu>
              </Dropdown>
            </NavbarItem>
          ) : (
            <NavbarItem key={`${item.title}-${index}`}>
              <Link href={item.path}>{item.title}</Link>
            </NavbarItem>
          )
        )}
      </NavbarContent>
    </Navbar>
  )
}

关键修改点

  1. 状态函数优化:handleDropdownToggle接收Dropdown组件onOpenChange传递的isOpen参数,直接根据组件的打开状态设置activeDropdown,确保内外状态完全同步。
  2. 切换逻辑简化:点击新下拉时自动替换活跃索引(关闭旧下拉),点击已展开的下拉则直接关闭,无需额外操作。

修改后点击任意下拉菜单都会直接切换状态,无需两次点击。

内容的提问来源于stack exchange,提问作者Carlos Casado Vargas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:13:20