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

React中点击单个Dropdown组件却全部展开的问题求助

问题分析

你遇到的问题核心在于:如果是希望同一时间仅展开一个下拉菜单,当前代码中每个Dropdown组件独立维护自己的isActive状态,无法实现互斥展开;如果是点击单个菜单却触发三个同时展开,大概率是CSS布局导致下拉层重叠,看起来像同时展开(从你提供的代码看,子组件独立状态本身不会触发这个问题)。

解决方案

根据你的需求,分两种场景给出实现:

场景1:允许同时展开多个下拉菜单

如果希望多个菜单可以同时展开,当前代码逻辑是正确的,只需调整CSS避免下拉层重叠:

  1. 给Dropdown的容器添加position: relative
  2. 给下拉列表添加position: absolute,确保每个下拉层相对于自身父元素定位

修改后的Dropdown组件:

const Dropdown = ({name, selected, setSelected, options}) => {
  const [isActive, setIsActive] = useState(false);

  return (
    <div className='bg-white cursor-pointer w-[100px] relative'>
      <div className='flex justify-between items-center p-2' onClick={() => setIsActive(!isActive)}>
        {name}
        <span><AiOutlineArrowDown /></span>
      </div>
      {
        isActive && (
          <div className='absolute top-full left-0 right-0 bg-white border-t'>
            {options.map((option, index) => (
              <div
                key={index}
                onClick={() => {
                  setSelected(option);
                  setIsActive(false)
                }}
                className='p-2 hover:bg-gray-100'
              >
                {option}
              </div>
            ))}
          </div>
        )
      }
    </div>
  )
}

export default Dropdown

场景2:同一时间仅展开一个下拉菜单

如果希望点击一个菜单时自动收起其他菜单,需要由父组件Navbar统一控制展开状态:

修改Navbar组件

const Navbar = () => {
  // 存储每个菜单的选中值,避免共享状态导致选中项同步变化
  const [selected, setSelected] = useState({
    Jobs: null,
    Talent: null,
    Reports: null
  });
  // 存储当前展开的菜单名称,实现互斥展开
  const [expandedMenu, setExpandedMenu] = useState(null);

  // 切换菜单展开状态
  const toggleMenu = (menuName) => {
    setExpandedMenu(expandedMenu === menuName ? null : menuName);
  };

  // 更新对应菜单的选中值
  const updateSelected = (menuName, option) => {
    setSelected(prev => ({...prev, [menuName]: option}));
    toggleMenu(menuName); // 选中后自动收起菜单
  };

  return (
    <div className='flex justify-evenly items-center h-[80px] bg-black'>
      <div className='logo_container'>
        <img src={logo} alt='' />
      </div>
      <div className='flex w-fit gap-2'>
        <Dropdown 
          name={'Jobs'} 
          selected={selected.Jobs} 
          onSelect={(option) => updateSelected('Jobs', option)}
          options={['My Jobs', 'All Job Posts', 'All Contracts', 'Post Job']}
          isActive={expandedMenu === 'Jobs'}
          onToggle={() => toggleMenu('Jobs')}
        />
        <Dropdown 
          name={'Talent'} 
          selected={selected.Talent} 
          onSelect={(option) => updateSelected('Talent', option)}
          options={['My Jobs', 'All Job Posts', 'All Contracts', 'Post Job']}
          isActive={expandedMenu === 'Talent'}
          onToggle={() => toggleMenu('Talent')}
        />
        <Dropdown 
          name={'Reports'} 
          selected={selected.Reports} 
          onSelect={(option) => updateSelected('Reports', option)}
          options={['My Jobs', 'All Job Posts', 'All Contracts', 'Post Job']}
          isActive={expandedMenu === 'Reports'}
          onToggle={() => toggleMenu('Reports')}
        />
      </div>
    </div>
  )
}

export default Navbar

修改Dropdown组件

const Dropdown = ({name, selected, onSelect, options, isActive, onToggle}) => {
  return (
    <div className='bg-white cursor-pointer w-[100px] relative'>
      <div className='flex justify-between items-center p-2' onClick={onToggle}>
        {name}
        <span><AiOutlineArrowDown /></span>
      </div>
      {
        isActive && (
          <div className='absolute top-full left-0 right-0 bg-white border-t'>
            {options.map((option, index) => (
              <div
                key={index}
                onClick={() => onSelect(option)}
                className='p-2 hover:bg-gray-100'
              >
                {option}
              </div>
            ))}
          </div>
        )
      }
    </div>
  )
}

export default Dropdown
额外优化点
  • 给options.map的子元素添加key属性,避免React警告
  • 将共享的selected状态改为对象,确保每个菜单的选中值独立,不会互相影响

内容的提问来源于stack exchange,提问作者Daniyal Sohail

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 11:15:56