react实现折叠面板
React 实现折叠面板的方法
使用 useState 管理状态
通过 React 的 useState 钩子管理折叠面板的展开/折叠状态。定义一个布尔值状态变量(如 isExpanded)和对应的更新函数(如 setIsExpanded)。
import React, { useState } from 'react';
function CollapsePanel({ title, children }) {
const [isExpanded, setIsExpanded] = useState(false);
return (
<div>
<button onClick={() => setIsExpanded(!isExpanded)}>
{title} {isExpanded ? '▲' : '▼'}
</button>
{isExpanded && <div>{children}</div>}
</div>
);
}
添加动画效果
使用 CSS 过渡或第三方库(如 react-transition-group)实现平滑的展开/折叠动画。
import { CSSTransition } from 'react-transition-group';
function CollapsePanelWithAnimation({ title, children }) {
const [isExpanded, setIsExpanded] = useState(false);
return (
<div>
<button onClick={() => setIsExpanded(!isExpanded)}>
{title} {isExpanded ? '▲' : '▼'}
</button>
<CSSTransition
in={isExpanded}
timeout={300}
classNames="collapse"
unmountOnExit
>
<div>{children}</div>
</CSSTransition>
</div>
);
}
对应的 CSS 样式:
.collapse-enter {
max-height: 0;
overflow: hidden;
}
.collapse-enter-active {
max-height: 1000px;
transition: max-height 300ms ease-in-out;
}
.collapse-exit {
max-height: 1000px;
}
.collapse-exit-active {
max-height: 0;
transition: max-height 300ms ease-in-out;
}
使用第三方库
快速实现折叠面板可以借助现成的 React 组件库,如 antd 或 material-ui。
使用 antd 的 Collapse 组件:
import { Collapse } from 'antd';
const { Panel } = Collapse;
function AntdCollapse() {
return (
<Collapse>
<Panel header="标题 1" key="1">
内容 1
</Panel>
<Panel header="标题 2" key="2">
内容 2
</Panel>
</Collapse>
);
}
使用 material-ui 的 ExpansionPanel:
import {
ExpansionPanel,
ExpansionPanelSummary,
ExpansionPanelDetails,
Typography,
} from '@material-ui/core';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
function MaterialUICollapse() {
return (
<ExpansionPanel>
<ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
<Typography>标题</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Typography>内容</Typography>
</ExpansionPanelDetails>
</ExpansionPanel>
);
}
支持多面板控制
通过状态管理实现多面板的独立控制或手风琴效果(每次只展开一个面板)。
function MultiCollapsePanels() {
const [activePanel, setActivePanel] = useState(null);
const panels = [
{ id: 1, title: '面板 1', content: '内容 1' },
{ id: 2, title: '面板 2', content: '内容 2' },
];
return (
<div>
{panels.map((panel) => (
<div key={panel.id}>
<button onClick={() => setActivePanel(activePanel === panel.id ? null : panel.id)}>
{panel.title} {activePanel === panel.id ? '▲' : '▼'}
</button>
{activePanel === panel.id && <div>{panel.content}</div>}
</div>
))}
</div>
);
}
自定义样式与交互
通过 CSS 和事件处理实现更丰富的交互效果,如悬停反馈、图标旋转等。
function StyledCollapsePanel({ title, children }) {
const [isExpanded, setIsExpanded] = useState(false);
return (
<div style={{ border: '1px solid #ddd', borderRadius: '4px', margin: '8px 0' }}>
<button
onClick={() => setIsExpanded(!isExpanded)}
style={{
width: '100%',
padding: '12px',
textAlign: 'left',
background: '#f5f5f5',
border: 'none',
cursor: 'pointer',
display: 'flex',
justifyContent: 'space-between',
}}
>
<span>{title}</span>
<span style={{ transform: isExpanded ? 'rotate(180deg)' : 'none', transition: 'transform 0.2s' }}>
▼
</span>
</button>
<div
style={{
padding: isExpanded ? '12px' : '0',
maxHeight: isExpanded ? '1000px' : '0',
overflow: 'hidden',
transition: 'all 0.3s ease',
}}
>
{children}
</div>
</div>
);
}






