Material-UI手风琴无法实现单次展开问题求助
问题分析
你的问题出在每个InfoAccordion子组件都独立维护自己的expanded状态,多个手风琴之间没有共享状态,所以点击其中一个时,其他手风琴的状态不会被更新,自然无法实现“单次仅展开一个”的效果。
解决方案
把展开状态的管理逻辑提到父组件Investment.jsx中,让所有子组件共享同一个状态,这样就能统一控制所有手风琴的展开/关闭。
修改后的父组件(Investment.jsx)
import { useState } from 'react'; import InfoAccordion from './InfoAccordion'; const Investment = () => { // 父组件统一维护展开的面板ID,初始值设为null(全部关闭)或某个默认ID const [expanded, setExpanded] = useState(null); const handleChange = (panelId) => (event, newExpanded) => { // 点击时更新展开状态:如果当前要展开,就设为对应panelId;否则设为null(关闭) setExpanded(newExpanded ? panelId : null); }; return ( <div> {investmentScreenData.map((item) => ( <InfoAccordion key={item.id} item={item} expanded={expanded} handleChange={handleChange} /> ))} </div> ); }; export default Investment;
修改后的子组件(InfoAccordion.jsx)
// 去掉子组件自己的useState,直接使用父组件传入的props const InfoAccordion = ({ item, expanded, handleChange }) => { return ( <StyledAccordion expanded={expanded === item.id} onChange={handleChange(item.id)} > <StyledAccordionSummery aria-controls={`panel${item.id}-content`} id={`panel${item.id}-header`} > <Typography component='p' variant='p' fontSize={{ xs: '19px', sm: '24px', md: '19px', lg: '24px' }} fontWeight={500} fontFamily={'inter'} color={'text.darkGreen'} > {item.title} </Typography> </StyledAccordionSummery> <StyledAccordionDetails> {item.points.map((point, index) => ( <StyledListitem key={index} disableGutters disablePadding> {/* 你的列表项内容 */} {point} </StyledListitem> ))} </StyledAccordionDetails> </StyledAccordion> ); }; export default InfoAccordion;
关键优化点
- 状态提升:将原本分散在子组件的状态统一到父组件,实现跨组件状态共享
- 唯一标识:使用
item.id作为手风琴的唯一标识,比index更可靠(避免数据顺序变化导致的key异常) - 无障碍优化:修改
aria-controls和id为动态值,确保每个手风琴的无障碍属性唯一
内容的提问来源于stack exchange,提问作者Sairam Gudiputi
相关产品推荐
相关产品推荐

