React报错TypeError: Cannot read properties of undefined(reading 'word')求助
问题分析与解决方案
核心错误原因
组件初始渲染阶段,newArr的初始值是空数组[],而i初始为0,此时newArr[i]就是undefined,直接访问newArr[i].word自然会抛出Cannot read properties of undefined的错误。虽然useEffect会在首次渲染后执行并更新newArr,但初始渲染时的错误已经发生了。
另外代码还有两个次要问题:
onClick={() => randomCard写法错误,不会触发函数,应该改为onClick={randomCard}或者onClick={() => randomCard()}- 用
arr.sort(() => Math.random() - 0.5)做洗牌并不够随机,不过这不是当前报错的原因,可后续优化。
修复方案
方案1:初始化newArr时直接处理数据
把newArr的初始值从空数组改为洗牌后的data,避免初始渲染时数组为空:
const shuffle = (arr) => [...arr].sort(() => Math.random() - 0.5); // 先拷贝原数组再排序,避免修改原data function Home({ data, num }) { const [newArr, setNewArr] = useState(shuffle(data)); // 直接初始化 const [i, setI] = useState(0); const randomCard = () => { if (i < newArr.length - 1) { setI(prevI => prevI + 1); // 用函数式更新,避免依赖旧的i值 } else { setNewArr(shuffle(data)); setI(0); } }; return ( <div> <div className="home-inner"> {num >= 1 ? ( <div className="home-stat"> <div onClick={randomCard} className="home-random"> {/* 修复onClick */} <div className="hr-card"> <p className="randomword">{newArr[i].word}</p> <p className="randomtranslate">{newArr[i].translate}</p> </div> </div> </div> ) : ( <div> <Link className="main-btn" to="/addcard"> Add </Link> </div> )} </div> </div> ); } export default Home;
方案2:渲染时添加空值判断
如果不想修改初始化逻辑,就在JSX里先判断newArr[i]是否存在,再渲染内容:
// 其他代码不变,修改return里的部分 return ( <div> <div className="home-inner"> {num >= 1 ? ( <div className="home-stat"> <div onClick={() => randomCard()} className="home-random"> {/* 修复onClick */} <div className="hr-card"> {newArr[i] ? ( // 添加判断 <> <p className="randomword">{newArr[i].word}</p> <p className="randomtranslate">{newArr[i].translate}</p> </> ) : ( <p>加载中...</p> // 可选的加载提示 )} </div> </div> </div> ) : ( <div> <Link className="main-btn" to="/addcard"> Add </Link> </div> )} </div> </div> );
额外优化提示
- 洗牌函数推荐用Fisher-Yates算法,比
sort更公平:
const shuffle = (arr) => { const newArr = [...arr]; for (let j = newArr.length - 1; j > 0; j--) { const k = Math.floor(Math.random() * (j + 1)); [newArr[j], newArr[k]] = [newArr[k], newArr[j]]; } return newArr; };
- 更新
i时用函数式更新setI(prevI => prevI + 1),避免因为闭包拿到旧的i值导致逻辑错误。
内容的提问来源于stack exchange,提问作者wch
相关产品推荐
相关产品推荐

