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

React JS嵌套手风琴实现的技术问题咨询

嵌套手风琴实现的常见问题与解决方案

1. 独立控制各层级展开/收起状态

不要用单个useState布尔值控制所有节点,改用对象或Map存储每个节点的展开状态,以节点唯一ID作为键:

const [expandedIds, setExpandedIds] = useState({});

const handleToggle = (id) => {
  setExpandedIds(prev => ({
    ...prev,
    [id]: !prev[id]
  }));
};

渲染时通过expandedIds[id]判断当前节点是否展开,每个节点点击时触发对应ID的状态切换,实现独立控制。

2. 替代多层map的最优实现:递归组件

嵌套结构天然适合递归渲染,编写一个可复用的AccordionItem组件,当节点包含子节点时,递归调用自身:

const AccordionItem = ({ item, expandedIds, onToggle }) => {
  const hasChildren = item.children && item.children.length > 0;
  const isExpanded = expandedIds[item.id];

  return (
    <div className="accordion-item">
      <div 
        className="accordion-header" 
        onClick={() => onToggle(item.id)}
      >
        {item.title}
        {hasChildren && <span>{isExpanded ? '▼' : '▶'}</span>}
      </div>
      {isExpanded && hasChildren && (
        <div className="accordion-content">
          {item.children.map(child => (
            <AccordionItem 
              key={child.id} 
              item={child} 
              expandedIds={expandedIds} 
              onToggle={onToggle}
            />
          ))}
        </div>
      )}
    </div>
  );
};

无论嵌套多少层,无需手动写多层map,代码简洁且扩展性强。

3. 改造为可复用React组件

将核心逻辑封装为两个组件:父组件Accordion负责状态管理,子组件AccordionItem负责单个节点渲染:

// 可复用的Accordion父组件
export const Accordion = ({ data }) => {
  const [expandedIds, setExpandedIds] = useState({});

  const handleToggle = (id) => {
    setExpandedIds(prev => ({
      ...prev,
      [id]: !prev[id]
    }));
  };

  return (
    <div className="accordion-container">
      {data.map(item => (
        <AccordionItem 
          key={item.id} 
          item={item} 
          expandedIds={expandedIds} 
          onToggle={handleToggle}
        />
      ))}
    </div>
  );
};

// 可复用的AccordionItem子组件
const AccordionItem = ({ item, expandedIds, onToggle }) => {
  const hasChildren = item.children && item.children.length > 0;
  const isExpanded = expandedIds[item.id];

  return (
    <div className="accordion-item">
      <div 
        className="accordion-header" 
        onClick={() => onToggle(item.id)}
        style={{ cursor: hasChildren ? 'pointer' : 'default' }}
      >
        {item.title}
        {hasChildren && <span className="toggle-icon">{isExpanded ? '▼' : '▶'}</span>}
      </div>
      {isExpanded && hasChildren && (
        <div className="accordion-content">
          {item.children.map(child => (
            <AccordionItem 
              key={child.id} 
              item={child} 
              expandedIds={expandedIds} 
              onToggle={onToggle}
            />
          ))}
        </div>
      )}
    </div>
  );
};

使用时只需传入符合结构的data即可:

<Accordion data={yourAccordionData} />

4. 专业开发中UI组件库的使用情况

是的,绝大多数专业项目会使用成熟的UI组件库,原因包括:

  • 节省开发时间,无需从零实现基础组件
  • 组件经过多场景测试,兼容性和稳定性更有保障
  • 内置无障碍支持,符合行业规范
  • 统一的设计语言,提升产品视觉一致性

react-bootstrap、Material-UI(MUI)是目前最主流的选择;semantic-ui-react因维护频率降低,使用占比有所下降,但仍有部分项目在使用。只有当项目有极高定制化需求或需要极小打包体积时,才会考虑完全自定义实现。


附:示例数据结构、样式文件

数据结构示例

const accordionData = [
  {
    id: '1',
    title: '一级菜单1',
    children: [
      {
        id: '1-1',
        title: '二级菜单1-1',
        children: [
          { id: '1-1-1', title: '三级菜单1-1-1' }
        ]
      },
      { id: '1-2', title: '二级菜单1-2' }
    ]
  },
  {
    id: '2',
    title: '一级菜单2',
    children: [
      { id: '2-1', title: '二级菜单2-1' }
    ]
  }
];

样式文件(accordion.css)

.accordion-container {
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
}

.accordion-item {
  border-bottom: 1px solid #e0e0e0;
}

.accordion-item:last-child {
  border-bottom: none;
}

.accordion-header {
  padding: 12px 16px;
  background-color: #f5f5f5;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.toggle-icon {
  font-size: 14px;
  color: #666;
}

.accordion-content {
  padding-left: 24px;
  background-color: #fff;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 06:16:17