为何React组件中反复出现'Uncaught TypeError: Cannot read properties of undefined'错误?
React组件读取
items时报错的原因分析 问题代码
export default function VideoDetail() { const { etag } = useParams(); const { isLoading, error, data: test, } = useQuery(["test"], async () => { return fetch("../../data/popular.json").then((res) => res.json()); }); const clickedVideo = test.items.find((v) => v.etag === etag); if (isLoading) return <p>Loading...</p>; if (error) return <p>{error.message}</p>; return console.log(clickedVideo); }
报错情况
前5次左右尝试控制台能正常输出值,但之后未做修改却持续报错,错误信息:
Uncaught TypeError: Cannot read properties of undefined (reading 'items') React Router caught the following error during render TypeError: Cannot read properties of undefined (reading 'items')
其他组件使用popular.json均无问题。
报错原因
核心问题是数据加载完成前就尝试访问test.items:
useQuery初始化时,data(即代码里的test)默认值为undefined- 你把
const clickedVideo = test.items.find(...)写在了isLoading判断之前,组件首次渲染、缓存失效(比如页面刷新、路由跳转后重新挂载)时,test还是undefined,此时访问test.items就会触发报错 - 前几次能正常输出是因为
useQuery缓存了请求结果,后续渲染时test已有值,但缓存失效后就会回到初始状态触发错误
另外原代码还有一个问题:return console.log(clickedVideo)不符合React组件要求,console.log返回undefined,React组件不能返回undefined,必须返回有效的React元素或null。
修复方案
方案1:调整代码顺序,确保数据加载完成后再处理
把clickedVideo的定义移到加载状态判断之后:
export default function VideoDetail() { const { etag } = useParams(); const { isLoading, error, data: test, } = useQuery(["test"], async () => { return fetch("../../data/popular.json").then((res) => res.json()); }); if (isLoading) return <p>Loading...</p>; if (error) return <p>{error.message}</p>; const clickedVideo = test.items.find((v) => v.etag === etag); console.log(clickedVideo); return <div>{JSON.stringify(clickedVideo)}</div>; // 返回有效的React元素 }
方案2:使用可选链避免访问undefined属性
如果不想调整顺序,可以用可选链操作符?.来防止报错:
const clickedVideo = test?.items?.find((v) => v.etag === etag) ?? null;
内容的提问来源于stack exchange,提问作者white
相关产品推荐
相关产品推荐

