React循环渲染列表时点击指定项切换图标并展示测试结果的实现方案
React数组map渲染时单项目图标切换与内容展示实现及优化
需求说明
- 点击列表迭代项的图标时,仅切换当前项的图标状态
- 点击图标同时展示当前项对应的测试结果
实现思路
最初的困惑在于不知道如何获取迭代项唯一标识处理单独状态切换,也不确定原有代码结构是否合理。最终通过组件封装解决了问题:将每个循环项封装为独立的单条数据组件,控制显示状态的布尔变量属于当前迭代组件的局部作用域,无需额外维护唯一标识与状态的关联关系。
实现代码
React组件代码
import { useState } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faMinus, faPlus } from '@fortawesome/free-solid-svg-icons'; // 单条学生信息组件 const Student = ({ student }) => { const [showTests, setShowTests] = useState(false); // 计算平均成绩的工具函数 const averageGrade = (grades) => { return grades.reduce((sum, grade) => sum + Number(grade), 0) / grades.length; }; return ( <div className="wrapper"> <div className="img-container"> <img src={student.pic} alt="学生头像" /> </div> <div className="content"> <h1> {student.firstName.toUpperCase()} {student.lastName.toUpperCase()} </h1> <p>邮箱:{student.email}</p> <p>公司:{student.company}</p> <p>技能:{student.skill}</p> <p>平均成绩:{averageGrade(student.grades)}%</p> {showTests && <TestResults results={student.tests} />} </div> <FontAwesomeIcon onClick={() => setShowTests(prev => !prev)} className="faIcon" icon={showTests ? faMinus : faPlus} /> </div> ); }; // 测试结果展示组件 const TestResults = ({ results }) => { return ( <div className="test-results"> {results.map((result, index) => ( <p key={index}>测试{index + 1}:{result}分</p> ))} </div> ); }; // 主列表组件 const Main = ({ filteredStudents }) => { return ( <div className="main" id="main"> {filteredStudents.map(student => ( <Student key={student.id} student={student} /> ))} </div> ); };
基础依赖引入(HTML端)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
可优化参考
- 组件命名修正:原代码中单个学生组件命名为
Students容易造成歧义,建议改为单数Student,更符合语义 - key属性位置修正:原代码把
key写在组件内部的根div上是错误的,应该在map渲染组件时给Student组件绑定key,React才能正确识别列表项的更新 - 状态更新写法优化:切换布尔状态时使用函数式更新
setShowTests(prev => !prev),避免闭包导致的状态更新异常 - Icon组件复用:无需写两个
FontAwesomeIcon组件,通过三元表达式动态判断icon属性即可,减少冗余代码 - 工具函数抽离:
averageGrade这类通用计算函数可以抽离到组件外部的工具文件中,避免重复渲染时重复创建函数 - 性能优化:如果列表数据量很大,可以给
Student组件包一层React.memo,减少不必要的重渲染 - 交互增强:可以给图标添加hover样式、点击反馈,也可以支持点击学生卡片空白区域切换展示状态,提升使用体验
内容的提问来源于stack exchange,提问作者Jason H
相关产品推荐
相关产品推荐

