React.js访问对象数组时报Cannot read properties of undefined错误如何解决
错误原因
- 组件渲染和useEffect的执行顺序问题:React组件首次渲染时,会先执行组件体内的逻辑(包括你写的
console.log('1:', arrayData[1])),之后才会触发useEffect里的PubSub订阅逻辑。在订阅到推送数据前,arrayData还是初始空数组。如果某一次推送的data不存在metrics字段,setArrayData(data.metrics)会把arrayData赋值为undefined,此时访问arrayData[1]就会抛出「Cannot read properties of undefined (reading '1')」的错误。 - 浏览器console的打印特性是你混淆的另一个原因:console打印引用类型(数组、对象)时,展示的是引用的实时值,不是打印时刻的快照。你看到控制台输出完整的metrics数组,是你展开打印结果的时候数据已经更新了,不代表你执行打印代码的那一刻数组就已经有对应索引的元素。
解决方案
- 第一步:给状态赋值前加字段校验,避免把arrayData设为非数组类型
const PubSubFunctional = () => { // 初始值保持空数组即可 const [arrayData, setArrayData] = useState([]); useEffect(() => { PubSub.subscribe('testingtopic').subscribe({ next: (data) => { try { // 先校验metrics是数组类型再更新状态 if (data && Array.isArray(data.metrics)) { setArrayData(data.metrics); } } catch (error) { console.log('Error, Try again!'); } }, error: (error) => console.error(error), close: () => console.log('Done'), }); }, []);
- 第二步:访问数组元素时用可选链做安全兜底,避免报错
// 访问数组索引加可选链,就算arrayData为undefined也不会抛错 console.log('1:', arrayData?.[1]); // 如果要访问元素内部属性,继续叠加可选链即可 console.log('索引1的name值:', arrayData?.[1]?.name);
- 第三步:UI层渲染时加加载态判断,避免渲染异常
return ( <div> {/* 写法1:长度判断后渲染,否则显示占位提示 */} {arrayData.length > 1 ? arrayData[1].value : '数据加载中...'} {/* 写法2:可选链配合空值合并运算符设置默认值 */} <p>{arrayData?.[1]?.value ?? '暂无数据'}</p> </div> ) }
内容的提问来源于stack exchange,提问作者Peter M.
相关产品推荐
相关产品推荐

