React数组元素映射问题:技能列表可见项无法渲染及代码优化求助
问题分析与解决方案
先帮你梳理下代码里的几个核心问题,这也是导致可见技能无法正常展示的原因:
- 全局变量引发的状态混乱:
lengthCount、maxIndex、skill这些变量都定义在组件外部,组件每次重新渲染时不会重置这些变量,会导致累加的长度、收集的技能数据完全不符合预期。 - 数据存储与渲染不匹配:你把
item.name(字符串)push到skill数组里,但后面渲染时却试图访问perSkill.id和perSkill.name——字符串根本没有这些属性,自然渲染不出内容。 - 长度判断逻辑错误:你先判断当前
lengthCount <=20(但需求是总长度超过25)再添加技能,之后才累加长度,这会导致最后一个技能可能让总长度超标却被错误加入。 - key值不合法:渲染时用
perSkill.id当key,但perSkill是字符串,会触发React警告,也不符合key的规范。
下面是修复并优化后的代码:
import { useMemo } from 'react'; const skills = [ { id: 1, name: "Html" }, { id: 2, name: "css" }, { id: 3, name: "JavaScript" }, { id: 4, name: "React" }, { id: 5, name: "Node.js" }, // 其他技能... ]; const Skill = () => { // 把阈值抽成常量,方便后续修改 const MAX_TOTAL_LENGTH = 25; // 使用useMemo缓存计算结果,避免每次渲染重复计算 const { visibleSkills, hiddenCount } = useMemo(() => { let totalLength = 0; const visible = []; for (const skill of skills) { // 先预判添加当前技能后的总长度是否超标 const newTotal = totalLength + skill.name.length; if (newTotal > MAX_TOTAL_LENGTH) { break; } visible.push(skill); totalLength = newTotal; } return { visibleSkills: visible, hiddenCount: skills.length - visible.length }; }, []); // 依赖为空,仅在组件首次渲染时计算一次 return ( <div className="wrapper"> <div> {visibleSkills.map((skill) => ( <span key={skill.id} className="element"> {skill.name} </span> ))} {/* 仅当有隐藏技能时才显示数量 */} {hiddenCount > 0 && `+${hiddenCount}`} </div> </div> ); }; export default Skill;
优化说明:
- 状态隔离:把所有计算变量移到组件内部的
useMemo回调中,避免全局变量的副作用,保证每次计算都基于原始的skills数组。 - 逻辑修正:先计算添加当前技能后的总长度,判断是否超标后再决定是否加入可见列表,确保总长度不会超出限制。
- 性能优化:用
useMemo缓存计算结果,若skills数组固定,无需每次渲染都重新遍历计算。 - 边界处理:只有当
hiddenCount > 0时才显示+N,避免总长度未超标时出现多余的+0。 - 规范key值:使用技能的
id作为key,符合React的key规范,避免警告。
内容的提问来源于stack exchange,提问作者Vardan Hambardzumyan
相关产品推荐
相关产品推荐

