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

ReactJS开发:如何实现手风琴组件同一时间仅保持一个激活展开状态

实现逻辑说明

原来的实现中每个子组件单独维护自己的展开状态,所以多个模块可以同时展开。要实现同一时间仅展开一个的手风琴效果,只需要把展开状态的管理权提升到父组件,由父组件统一记录当前唯一激活的模块索引即可。

修改后的父组件代码

import { useState } from 'react';
import ListItem from './ListItem'; // 可根据你的实际文件引入路径调整

function App() {
  // 记录当前激活展开的模块索引,null为全部收起,设为0可默认展开第一个
  const [activeIndex, setActiveIndex] = useState(null);
  const data = [
    {
      title: "Build test task",
      items: [
        "Create repositor",
        "Implement designs",
        "Implement functionality",
      ],
    },
    {
      title: "Submit your test task",
      items: [
        "Open email client",
        "Sent link information to careers@cornercasetech.com",
      ],
    },
    {
      title: "Participate in tech interview",
      items: ["Talk with HR", "Talk with Tech team"],
    },
    {
      title: "Reciece anster",
      items: ["Receive answers", "Start your IT career"],
    },
  ];

  // 切换激活状态的逻辑:点击已激活项则收起,否则切换为点击项
  const toggleActive = (index) => {
    setActiveIndex(activeIndex === index ? null : index);
  };

  return (
    <div className="App">
      <header className="App-header">
        <h1>CCT Lab Process</h1>
      </header>
      <div className="App-content">
      {data.map((dataObject, index) => (
        <ListItem 
          key={index} 
          listData={dataObject} 
          listNumber={index + 1} 
          isActive={activeIndex === index}
          onToggle={() => toggleActive(index)}
        />
      ))}
      </div>

    </div>
  );
}
export default App;

修改后的子组件代码

子组件不需要再维护自己的展开状态,直接接收父组件传递的props即可:

// 注意如果CheckedIcon是单独引入的要保留引入逻辑
function ListItem({ listNumber, listData, isActive, onToggle }) {
  return (
    <div className="List">
      <div className="List-section" onClick={onToggle}>
        <div className="Section-item">{listNumber}</div>
        <p className="Section-title">{listData.title}</p>
      </div>
      {isActive && (
        <div className="List-paragraph">
          {listData.items.map((paragraphItem, index) => (
            <div className="Paragraph-container" key={index}>
              <CheckedIcon  />
              <p className="Paragraph-item">{paragraphItem}</p>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}
export default ListItem;

可选调整

如果不需要点击已激活项收起的效果,仅支持点击其他项切换,把父组件的toggleActive方法修改为如下即可:

const toggleActive = (index) => {
  setActiveIndex(index);
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 03:06:02