React渲染图片时报Cannot read properties of undefined (reading '0')如何解决
报错解决方法
问题根源
该TypeError: Cannot read properties of undefined (reading '0')报错是因为数据未完成请求时就访问了可能不存在的深层属性,同时状态逻辑存在多处错误:
- 初始值设置错误:
Data初始值设为空数组[],但接口请求后存储的是单条文章对象,首次渲染时Data不存在images属性,访问Data.images[0]直接触发报错 - 加载状态逻辑倒置:请求接口拿到数据后你将
loading设为true,正确逻辑应为请求结束后关闭加载状态,你当前的逻辑会导致数据请求完成后仍先执行内容渲染逻辑,提前触发属性读取报错 - 无安全访问校验:未做属性存在性判断,即使数据请求完成,也可能存在文章无配图、
images数组为空的情况,同样会触发报错
修复步骤
- 修正
Data初始值为null,匹配后续存储的对象类型 - 调整加载状态逻辑:请求前
loading为true,拿到数据后将loading设为false,仅在加载结束后渲染内容 - 用可选链
?.做属性安全访问,避免深层属性读取报错 - 规范
useParams取值写法,补充路由参数依赖避免更新异常
修复后完整代码
import React, { useEffect, useState } from 'react'; import './SinglePage.css'; import Style from '../../components/styles/Style'; import Logo from '../../components/Logo/Logo'; import Navbar from '../../components/Navbar/Navbar'; import RightBar from '../../components/RightBar/RightBar'; import { useParams } from 'react-router'; import API from '../../api/Api'; import Loading from '../../components/loading/Loading'; const SinglePage = () => { const [loading, setLoading] = useState(true); // 初始值改为null,匹配后续存储的对象类型 const [Data, setData] = useState(null); const [message, setMessage] = useState(false); // 规范解构获取路由id const { id } = useParams(); const URL = 'http://localhost:8001/' useEffect(() => { API.get("api/GetPosts").then((res) => { if (res.data.AllData.length === 0) { setMessage(true); } else { const card = res.data.AllData.find(x => x._id === id) setData(card); } }).finally(() => { // 请求完成后关闭加载状态 setLoading(false); }) }, [id]) // 补充id为依赖项,避免路由参数变化时不重新请求 return ( <> <div> <Logo /> <Navbar /> <div style={Style}> <RightBar /> <div className="SinglePage-Container"> {loading && ( <div style={{margin:'0 auto', marginTop:'2rem', display:'flex', justifyContent:'center', alignItems:'center'}}> <Loading/> </div> )} {/* 加载结束后才渲染内容 */} {!loading && ( message ? ( <div style={{margin:'0 auto', marginTop:'2rem', display:'flex', justifyContent:'center', alignItems:'center'}}> <h1>لا يوجد مقالة في هذا الرابط </h1> </div> ) : Data && ( <> <div className="SinglePage-Image"> {/* 用可选链安全访问深层属性 */} <img src={`${URL}${Data?.images?.[0]?.filename || ''}`} alt=''/> </div> <div className="SinglePage-Title"> {Data.title} </div> <p> {Data.article} </p> </> ) )} </div> </div> </div> </> ) } export default SinglePage
内容的提问来源于stack exchange,提问作者abderaouf abdou
相关产品推荐
相关产品推荐

