JavaScript遍历数组仅得最后值 控制台与页面渲染结果不符
遍历数组渲染异常问题排查与修复
问题根因
- 你代码中定义的
dat是for循环外部的单值变量,每次循环执行dat = i时,都会直接覆盖上一次存储的内容,本身不具备留存所有循环遍历值的能力:- 第一次循环i=0时,dat被赋值为0,此时立刻执行
console.log(dat),控制台输出0 - 第二次循环i=1时,dat被覆盖为1,此时立刻执行
console.log(dat),控制台输出1
- 第一次循环i=0时,dat被赋值为0,此时立刻执行
- 控制台能看到两次输出,是因为打印动作和循环赋值是同步执行的,能捕捉到每一次循环的临时状态;但页面渲染的执行时机是for循环全部跑完之后,此时dat已经被最后一次循环的赋值覆盖为1,自然只能显示1,两者出现结果差异完全符合代码运行逻辑,不是无理由的异常。
- 额外提示:你粘贴的原始for循环存在语法缺失,标准for循环需要在括号内写全三个部分(循环初始值、终止条件、循环变量自增),当前代码漏写了自增逻辑
i++,如果按原样运行会陷入死循环,应该是代码粘贴时的遗漏。
修复方案
结合代码中使用<Loader/>的JSX开发场景,核心调整思路是用数组作为值的集合容器,不要依赖外部单值变量暂存循环内容,避免覆盖问题,示例代码如下:
if (Event.data.length) { // 遍历数组,直接为每一项生成独立的渲染节点,收集为数组 const renderContent = Event.data.map((item, index) => { return <div key={index}>当前遍历索引:{index}</div> }) // 直接把收集好的内容渲染到页面 return <div>{renderContent}</div> } else { return <Loader /> }
如果坚持使用原生for循环实现,也要把每次遍历的值追加到数组中存储,不要直接覆盖单值变量:
if (Event.data.length) { const valueList = [] // 用数组存所有循环过程值 for (let i = 0; i < Event.data.length; i++) { valueList.push(i) // 追加值到数组,不覆盖 console.log(valueList) } // 渲染时把数组内容映射为独立节点即可 return <div>{valueList.map(num => <div key={num}>{num}</div>)}</div> } else { return <Loader /> }
内容的提问来源于stack exchange,提问作者Abhinav peter
相关产品推荐
相关产品推荐

