You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 23:45:47