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

React中如何单独切换嵌套的reactstrap Collapse组件?求助

解决Reactstrap Collapse嵌套数据下单独切换的问题

你的问题根源在于所有折叠区域共享了同一个open状态变量——当你点击任意按钮时,这个全局的状态会被切换,导致所有绑定它的Collapse组件一起展开/折叠。要实现单独控制,我们需要给每个二级项维护独立的展开状态。

具体解决方案

  1. 修改状态结构:把单个布尔值open改成一个对象openItems,用每个二级项的唯一标识作为键(比如orderPartsId,如果存在重复风险,就用orderId-orderPartsId的组合键),值为布尔值表示是否展开。
  2. 更新toggle方法:让toggle接收一个唯一标识参数,只切换对应项的状态。
  3. 绑定对应状态:每个Collapse组件的isOpen属性绑定到openItems中对应项的值。

修改后的完整代码

const data = [
  {"orderId":1,"orderNo":"123", "orderParts":[{"orderPartsId":1,"orderPrtNo":"OP-1", "regTokens":["Token1", "Token2","Token3"]}] }, 
  {"orderId":2,"orderNo":"456", "orderParts":[{"orderPartsId":1,"orderPrtNo":"OP-1", "regTokens":["Token1","Token3"]}] }, 
  {"orderId":3,"orderNo":"789", "orderParts":[{"orderPartsId":1,"orderPrtNo":"OP-1", "regTokens":["Token1", "Token2","Token3", "Token4"]}] } 
];
const {Component, Fragment} = React;
const {Button, Collapse} = Reactstrap;

class Menu extends Component {
  constructor(props) {
    super(props);
    // 用对象存储每个二级项的展开状态,初始为空(都折叠)
    this.state = { openItems: {} };
  }

  // 接收唯一标识,切换对应项的状态
  toggle = (itemKey) => {
    this.setState(prevState => ({
      openItems: {
        ...prevState.openItems,
        [itemKey]: !prevState.openItems[itemKey]
      }
    }));
  };

  render() {
    return (
      <div>
        {data.map((levelOneItem, i) => (
          <div key={levelOneItem.orderId}>
            <div> Order Id: {levelOneItem.orderId} </div>
            {levelOneItem.orderParts.map((levelTwoItem, j) => {
              // 生成唯一键,避免不同order下相同orderPartsId冲突
              const itemKey = `${levelOneItem.orderId}-${levelTwoItem.orderPartsId}`;
              return (
                <div key={itemKey}>
                  <div> Order Part Id: {levelTwoItem.orderPartsId} </div>
                  <Button onClick={() => this.toggle(itemKey)}>Display Token</Button>
                  <Collapse isOpen={this.state.openItems[itemKey] || false}>
                    <div>
                      {levelTwoItem.regTokens.map((levelThreeItem, k) => (
                        <span key={k}> {levelThreeItem} </span>
                      ))}
                    </div>
                  </Collapse>
                </div>
              );
            })}
          </div>
        ))}
      </div>
    );
  }
}

ReactDOM.render(<Menu />, document.getElementById("root"));
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reactstrap/8.4.1/reactstrap.min.js"></script>
<div id="root"></div>

关键改动说明

  • 状态管理:openItems对象可以精准记录每个二级项的展开状态,不会互相干扰。
  • 唯一键:用orderId-orderPartsId组合作为key,避免不同一级项中二级项ID重复导致的状态混乱。
  • toggle方法:通过展开运算符复制原状态,只修改对应key的值,保证状态更新的不可变性。

这样修改后,每个按钮只会控制自己对应的折叠区域,点击展开/折叠都不会影响其他项啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 07:27:36