React中如何用while循环遍历数组并传索引?遇未定义错误求解
React循环渲染问题:错误修复与替代方案
错误原因
把mainLoop.leagueOdds[0].league的索引换成循环变量i后出现Cannot read properties of undefined (reading 'league'),核心问题是**mainLoop.leagueOdds数组的实际长度不足28**。当i超过数组现有元素的索引范围时,mainLoop.leagueOdds[i]会变成undefined,无法读取league属性。
修复后的While循环代码
如果必须固定循环28次,要先判断当前索引对应的元素是否存在,避免报错:
{(function (Arr, i, len) { while (++i <= len) { // 先检查元素是否存在,不存在就跳过这次循环 const leagueItem = mainLoop.leagueOdds[i]; if (!leagueItem) continue; const items = leagueItem.league; console.log(i); Arr.push(<Accordion.Item eventKey={i}> <Accordion.Header>{items.id} {data.name} #{i}</Accordion.Header> <Accordion.Body></Accordion.Body> </Accordion.Item>) } return Arr; })([], 0, 28)}
如果mainLoop.leagueOdds的长度就是你需要的循环次数,更合理的写法是用数组长度代替硬编码的28:
{(function (Arr, i, len) { len = mainLoop.leagueOdds.length; while (++i <= len) { // 注意i从1开始,数组索引要减1对应正确元素 const items = mainLoop.leagueOdds[i-1].league; console.log(i); Arr.push(<Accordion.Item eventKey={i}> <Accordion.Header>{items.id} {data.name} #{i}</Accordion.Header> <Accordion.Body></Accordion.Body> </Accordion.Item>) } return Arr; })([], 0)}
更符合React风格的循环替代方案
React中很少用自执行函数+while循环生成元素,推荐以下简洁写法:
1. Array.from 生成固定次数循环
{Array.from({ length: 28 }, (_, index) => { const realIndex = index; // 根据实际需求调整索引对应关系 const leagueItem = mainLoop.leagueOdds[realIndex]; if (!leagueItem) return null; const items = leagueItem.league; return ( <Accordion.Item eventKey={index + 1} key={index}> <Accordion.Header>{items.id} {data.name} #{index + 1}</Accordion.Header> <Accordion.Body></Accordion.Body> </Accordion.Item> ); })}
2. 直接遍历目标数组(推荐)
如果mainLoop.leagueOdds的长度就是循环次数,直接用map最简洁:
{mainLoop.leagueOdds.map((item, index) => { const items = item.league; return ( <Accordion.Item eventKey={index + 1} key={index}> <Accordion.Header>{items.id} {data.name} #{index + 1}</Accordion.Header> <Accordion.Body></Accordion.Body> </Accordion.Item> ); })}
3. 封装自执行函数用for循环
{(() => { const elements = []; const maxCount = 28; for (let i = 0; i < maxCount; i++) { const leagueItem = mainLoop.leagueOdds[i]; if (!leagueItem) continue; const items = leagueItem.league; elements.push( <Accordion.Item eventKey={i + 1} key={i}> <Accordion.Header>{items.id} {data.name} #{i + 1}</Accordion.Header> <Accordion.Body></Accordion.Body> </Accordion.Item> ); } return elements; })()}
内容的提问来源于stack exchange,提问作者Krispy
相关产品推荐
相关产品推荐

