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

React中如何实现仅同时打开一个UncontrolledCollapse并关闭其他

如何让Reactstrap的多个Collapse组件互斥展开(仅保持一个激活状态)

我在使用Reactstrap的UncontrolledCollapse组件时遇到问题:当存在多个该组件时,打开一个后再打开另一个,之前的不会自动关闭。需要实现点击某个toggle时,仅让对应的内容展开,同时关闭其他所有已展开的内容。

当前代码逻辑如下:

export default function Header(args) {
  return (
    <Nav>
      <NavItem>
        <NavLink href="#" id="toggle-1">
          Toggle 1
        </NavLink>
        <UncontrolledCollapse toggler="#toggle-1">
          Content 1 Here                                
        </UncontrolledCollapse>
      </NavItem>
      <NavItem>
        <NavLink href="#" id="toggle-2">
          Toggle 2
        </NavLink>
        <UncontrolledCollapse toggler="#toggle-2">
          Content 2 Here                                
        </UncontrolledCollapse>
      </NavItem>
    </Nav>
  )
}

解决方案:改用受控的Collapse组件

UncontrolledCollapse是独立管理自身状态的,没法实现跨组件的状态同步。要实现互斥展开,需要改用受控的Collapse组件,通过父组件统一管理激活状态:

  1. 用useState维护当前激活的collapse ID
  2. 为每个toggle添加点击事件,更新激活状态为对应的ID
  3. 每个Collapse组件通过isOpen属性判断是否为当前激活项

修改后的代码如下:

import { useState } from 'react';
import { Nav, NavItem, NavLink, Collapse } from 'reactstrap';

export default function Header(args) {
  // 初始化激活状态为null(全部关闭),或指定默认激活的ID(比如'toggle-1')
  const [activeCollapse, setActiveCollapse] = useState(null);

  const handleToggle = (toggleId) => {
    // 点击同一个toggle时切换状态,点击不同的则直接切换为目标ID
    setActiveCollapse(prev => prev === toggleId ? null : toggleId);
  };

  return (
    <Nav>
      <NavItem>
        <NavLink 
          href="#" 
          id="toggle-1"
          onClick={() => handleToggle('toggle-1')}
        >
          Toggle 1
        </NavLink>
        <Collapse isOpen={activeCollapse === 'toggle-1'}>
          Content 1 Here                                
        </Collapse>
      </NavItem>
      <NavItem>
        <NavLink 
          href="#" 
          id="toggle-2"
          onClick={() => handleToggle('toggle-2')}
        >
          Toggle 2
        </NavLink>
        <Collapse isOpen={activeCollapse === 'toggle-2'}>
          Content 2 Here                                
        </Collapse>
      </NavItem>
    </Nav>
  )
}

额外优化建议

如果有更多toggle项,可以把数据抽成数组循环渲染,避免重复代码:

const collapseItems = [
  { id: 'toggle-1', label: 'Toggle 1', content: 'Content 1 Here' },
  { id: 'toggle-2', label: 'Toggle 2', content: 'Content 2 Here' }
];

// 渲染时循环
{collapseItems.map(item => (
  <NavItem key={item.id}>
    <NavLink 
      href="#" 
      id={item.id}
      onClick={() => handleToggle(item.id)}
    >
      {item.label}
    </NavLink>
    <Collapse isOpen={activeCollapse === item.id}>
      {item.content}
    </Collapse>
  </NavItem>
))}

内容的提问来源于stack exchange,提问作者Teik Cheah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 11:20:28