React onClick触发后无法收起展开列表的HandleClick处理方法
问题根源
你的代码无法正常收起是三个逻辑错误叠加导致的:
- 状态类型混乱:初始给
isExpanded设的是布尔值false,后续逻辑又把它赋值为数字索引、null,全等判断时类型不匹配,条件永远无法命中 - 事件传参缺失:绑定点击事件时直接写
onClick={HandleClick},没有传入你逻辑里要用的index参数,函数运行时拿到的index实际是原生点击事件对象,根本不可能和状态值相等 - 逻辑和结构不匹配:从DOM结构看,展开按钮是单个学生成绩块的总开关,不在成绩列表的循环内部,完全不需要用索引标记展开状态,用布尔值做切换就足够
修复方案
直接把状态统一为布尔值,点击时直接切换状态即可,不需要额外判断索引,修正后代码如下:
const ExpandList = ({ students }) => { const { grades } = students; // 统一使用布尔值管理展开状态,初始为收起 const [isExpanded, setIsExpanded] = useState(false); // 点击直接切换展开状态,用函数式更新保证拿到最新状态 function HandleClick() { setIsExpanded(prev => !prev); } return ( <div className="grades"> <button onClick={HandleClick}> { isExpanded ? <ImMinus/> : <ImPlus/> } </button> {isExpanded ? ( <div className="grades"> {grades.map((grade, index) => <ul key={index}>Test {index + 1}: {grade}%</ul>)} </div> ) : null} </div> ) };
如果你后续要做多列表互斥的手风琴效果(同一时间只展开一个学生的成绩),需要把展开状态提升到父组件存储,值为当前展开项的唯一ID/索引,此时绑定事件时要传入当前项标识:
onClick={() => HandleClick(currentStudentId)},判断时比对存储的ID和当前项ID是否一致即可,不要混用布尔值、数字、null作为状态值,避免判断逻辑失效。
内容的提问来源于stack exchange,提问作者Scott2n
相关产品推荐
相关产品推荐

