React中访问state存储的对象数组属性报错如何解决?
问题根因
- 组件首次渲染时,
useEffect内的fetch异步请求还未返回,此时request状态是初始值空数组[],访问request[0]得到undefined,再读取undefined的属性就会直接抛出运行时错误。等请求完成、状态更新触发重渲染后,你才能正常拿到数组里的对象数据。 - 代码第三行打印存在拼写错误:将
request错写为requst,即使数据加载完成,该行也会触发变量未定义的错误。
修复方案
方案1:增加加载状态(推荐)
在请求完成前不渲染依赖接口数据的内容,从根源避免访问空值的问题,同时优化用户体验:
import React from 'react' function QuizApp() { const [request, setRequest] = React.useState([]) const [isLoading, setIsLoading] = React.useState(true) React.useEffect(() => { fetch('https://opentdb.com/api.php?amount=5') .then(res => res.json()) .then(data => { const formattedData = data.results.map(({ question, correct_answer, incorrect_answers }) => ({ question, correct_answer, incorrect_answers })) setRequest(formattedData) setIsLoading(false) }) .catch(err => { console.error('题目获取失败:', err) setIsLoading(false) }) }, []) // 加载阶段返回占位内容 if (isLoading) { return <div>题目加载中,请稍候...</div> } // 到这里数据已经完成赋值,可以安全访问属性 console.log(request[0]) console.log(request[0]["question"]) console.log(request[0].question) return ( <div className="quiz-wrap"> {request.map((quiz, idx) => ( <div key={idx} className="quiz-item"> {/* 接口返回的question带HTML转义字符,用以下方式正常渲染 */} <h3 dangerouslySetInnerHTML={{ __html: quiz.question }} /> {/* 后续渲染正确答案、错误选项的逻辑 */} </div> ))} </div> ) } export default QuizApp
方案2:可选链防御性访问
如果不想单独维护加载状态,可以用ES2020的可选链操作符?.做安全访问,当访问路径上出现null/undefined时会直接返回undefined,不会抛出错误:
// 首次渲染打印undefined,数据加载后打印对应问题内容,全程不会报错 console.log(request?.[0]?.question)
注意:opentdb接口返回的题目、答案字段包含HTML实体字符,直接作为文本渲染会出现
"这类转义内容,需要做转义处理后再展示,示例中使用的dangerouslySetInnerHTML是最简单的处理方式。
内容的提问来源于stack exchange,提问作者Abdullahi Olateju
相关产品推荐
相关产品推荐

