React Material UI实现点击ListItem展开时其他项折叠的方案
解决Material UI List点击单个项却展开所有项的问题
这个问题很典型——你现在应该是用了一个全局的布尔状态来控制所有列表项的展开/折叠,所以点击任何一项都会触发所有项的状态变化。咱们调整一下状态管理的方式就能轻松解决:
核心思路
把原来单一的布尔状态(比如expanded)改成跟踪当前展开项的唯一标识(比如国家的ID、名称或者索引),这样就能精准控制只有被点击的项切换展开/折叠状态。
修改步骤及代码示例
更新状态定义
把原来的布尔状态替换为存储当前展开项的标识,初始值设为null表示没有项展开:import { useState } from 'react'; // ...其他必要导入(比如List、ListItem、Collapse等) function YourListComponent() { // 用expandedId存储当前展开项的唯一标识,初始为null const [expandedId, setExpandedId] = useState(null); // ...其他代码(比如你的countries数据) }修改点击事件处理函数
点击列表项时,判断当前项的标识是否和expandedId一致:如果一致就折叠(设为null),不一致就展开(设为当前项的标识):const handleListItemClick = (itemId) => { setExpandedId(prevId => prevId === itemId ? null : itemId); };调整列表项的展开判断逻辑
在遍历渲染列表项时,给每个ListItem绑定点击事件,并让Collapse组件的in属性判断当前项的标识是否等于expandedId:{countries.map((country) => ( <div key={country.id}> <ListItem button onClick={() => handleListItemClick(country.id)}> <ListItemText primary={country.name} /> {/* 根据当前项是否展开切换图标 */} {expandedId === country.id ? <ExpandLess /> : <ExpandMore />} </ListItem> {/* 只有当expandedId等于当前项id时才展开 */} <Collapse in={expandedId === country.id} timeout="auto" unmountOnExit> <List component="div" disablePadding> <ListItem button className={classes.nested}> <ListItemText primary={`${country.name} 的子内容`} /> </ListItem> </List> </Collapse> </div> ))}
为什么原来的方法无效?
你之前用索引尝试但没成功,大概率是因为还是沿用了单一布尔状态——不管是用索引还是其他标识,只要状态是全局的布尔值,所有项都会共享这个状态,导致点击一个全展开。而用唯一标识跟踪当前展开项,就能实现“点击哪项哪项展开,其余保持折叠”的预期效果。
内容的提问来源于stack exchange,提问作者Venkaiah Yepuri
相关产品推荐
相关产品推荐

