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

如何为MUI手风琴组实现「全部展开」和「全部折叠」按钮?

实现MUI手风琴的全部展开/折叠功能

下面是完整的解决方案,既支持全局的「全部展开/折叠」控制,又保留单个手风琴的独立交互能力:

import { useState, useEffect } from 'react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Accordion from '@mui/material/Accordion';
import AccordionSummary from '@mui/material/AccordionSummary';
import AccordionDetails from '@mui/material/AccordionDetails';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';

const Logs = () => {
  const [cards, setCards] = useState([]);
  const [expandedStates, setExpandedStates] = useState([]);

  // 异步获取日志数据
  useEffect(() => {
    const fetchLogs = async () => {
      try {
        const response = await fetch('from-API');
        const data = await response.json();
        setCards(data);
        // 初始化所有手风琴为折叠状态
        setExpandedStates(new Array(data.length).fill(false));
      } catch (error) {
        console.error('日志加载失败:', error);
      }
    };

    fetchLogs();
  }, []);

  // 全部展开逻辑
  const handleExpandAll = () => {
    setExpandedStates(new Array(cards.length).fill(true));
  };

  // 全部折叠逻辑
  const handleCollapseAll = () => {
    setExpandedStates(new Array(cards.length).fill(false));
  };

  // 单个手风琴切换状态
  const handleAccordionToggle = (index) => {
    setExpandedStates(prevStates => {
      const updatedStates = [...prevStates];
      updatedStates[index] = !updatedStates[index];
      return updatedStates;
    });
  };

  return (
    <Box sx={{ p: 2 }}>
      {/* 控制按钮组 */}
      <Box sx={{ mb: 2, display: 'flex', gap: 1 }}>
        <Button variant="contained" onClick={handleExpandAll}>
          全部展开
        </Button>
        <Button variant="outlined" onClick={handleCollapseAll}>
          全部折叠
        </Button>
      </Box>

      {/* 手风琴列表 */}
      {cards.length > 0 ? (
        cards.map((card, index) => (
          <Accordion
            key={index}
            expanded={expandedStates[index]}
            onChange={() => handleAccordionToggle(index)}
            sx={{ mb: 1 }}
          >
            <AccordionSummary expandIcon={<ExpandMoreIcon />}>
              日志摘要 {card.id || `#${index + 1}`}
            </AccordionSummary>
            <AccordionDetails>
              {card.content || '日志详细内容'}
            </AccordionDetails>
          </Accordion>
        ))
      ) : (
        <Box sx={{ p: 3, textAlign: 'center', color: 'text.secondary' }}>
          暂无日志数据
        </Box>
      )}
    </Box>
  );
};

export default Logs;

关键实现说明

  • 状态管理:用expandedStates数组记录每个手风琴的展开状态,数组索引与日志条目一一对应,确保全局控制和单个交互互不冲突。
  • 异步数据处理:通过useEffect发起API请求,获取数据后初始化展开状态数组,避免空数组导致的渲染错误。
  • 全局控制逻辑:点击「全部展开/折叠」时,直接生成全true或全false的状态数组,批量更新所有手风琴的展开状态。
  • 单个交互保留:每个手风琴的onChange事件单独修改对应索引的状态,保留原生手风琴的点击切换功能。
  • UI细节优化:添加了间距、图标和空状态提示,提升整体用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 07:55:43