如何阻止Material UI多个可展开卡片同时展开?
问题原因
你当前所有卡片共用同一个布尔类型的expanded状态,任意卡片触发状态修改都会同步作用到全部卡片,所以会出现同时展开、同时收起的问题。
修复方案
只需要调整状态存储逻辑,将存储布尔值改为存储当前处于展开状态的卡片ID即可,具体修改如下:
- 调整state定义,初始值设为
null代表无卡片展开
// 原来的写法 // const [expanded, setExpanded] = useState(false); // 修改后 const [expandedId, setExpandedId] = useState(null);
- 修改展开点击事件的逻辑:如果点击的是当前已展开的卡片则收起,否则展开点击的卡片
const handleExpandClick = (id) => { setExpandedId(expandedId === id ? null : id); };
- 调整卡片中所有用到展开状态判断的逻辑,替换为当前卡片ID是否等于已展开ID的判断:
- IconButton的className判断、aria-expanded属性
- Collapse组件的in属性
另外你当前onClick的参数写法有冗余,可以删掉无用的形参避免歧义。
修改后的完整组件代码
const Featured = ({ featuredSection }) => { const classes = useStyles(); const [expandedId, setExpandedId] = useState(null); const handleExpandClick = (id) => { setExpandedId(expandedId === id ? null : id); }; const card = featuredSection.map((item, i) => { return ( <div key={item.id}> <CardWrapper> <Card className={classes.root}> <CardMedia className={classes.media} image={require(`../images/${item.name}.jpg`).default} title={item.title} /> <CardContent> ... </CardContent> <CardActions disableSpacing> <IconButton style={{ color: '#f5f5f5' }} className={clsx(classes.expand, { [classes.expandOpen]: expandedId === item.id, })} onClick={() => handleExpandClick(item.id)} aria-expanded={expandedId === item.id} aria-label='show more'> <ExpandMoreIcon /> </IconButton> </CardActions> <Collapse in={expandedId === item.id} timeout='auto' unmountOnExit> ... </Collapse> </Card> </CardWrapper> </div> ); }); return <>{card}</>; }; export default Featured;
内容的提问来源于stack exchange,提问作者agw2021
相关产品推荐
相关产品推荐

