React页面刷新时API调用报错:无法读取undefined的title属性
React应用页面刷新后API调用异常问题
问题表现
页面刷新时报错,无法正常渲染接口返回数据。
复现代码
import Base from "./Base"; import axios from "axios"; import { createData } from "../../utils"; import { useState, useEffect } from "react"; export default function Today(props) { const [scoops, setScoops] = useState(0); //Fetch api/scoops/today const fetchScoops = async () => { const res = await axios.get("http://localhost:8000/api/scoops/today/"); setScoops(res.data); }; useEffect(() => { fetchScoops(); }, []); console.log(scoops[0]); const rows = [ createData(0, 1, scoops[0].title, "http://example.com"), createData(1, 2, "Paul McCartney", "http://example.com"), createData(2, 3, "Tom Scholz", "http://example.com"), createData(3, 4, "Michael Jackson", "http://example.com"), createData(4, 5, "Bruce Springsteen", "http://example.com"), ]; return <Base rows={rows} duration="Today" />; }
控制台输出
> undefined > Today.js:20 {url: 'http://localhost:8000/api/scoops/1/', title: 'Hello World!', rank: 0, created_at: '2021-10-05T04:44:52.027336Z', updated_at: '2021-10-05T04:44:52.027336Z'}
报错信息
TypeError: Cannot read properties of undefined (reading 'title')
问题原因
- 初始状态
scoops被定义为数值类型0,第一次组件渲染时,异步API请求还未返回结果,此时scoops[0]的值为undefined - 代码直接访问
scoops[0].title,对undefined访问属性就会触发类型错误 - 等API请求完成后调用
setScoops更新状态,组件二次渲染时才能拿到正常的数组数据,所以控制台会先输出undefined,再输出正常的接口返回对象
解决方案
方案1:使用可选链语法(最简方案,已验证可用)
访问属性前加?.判断前置值是否存在,不存在时直接返回undefined不会报错:
scoops[0]?.title
方案2:修正初始状态类型
将scoops的初始值改为空数组,符合后续接口返回的数组类型:
const [scoops, setScoops] = useState([]);
方案3:增加加载状态判断
渲染前判断数据是否加载完成,未加载时显示Loading占位:
if (!scoops.length) return <div>加载中...</div> // 后续写正常的rows构造和return逻辑
内容的提问来源于stack exchange,提问作者Nabeel Hassan
相关产品推荐
相关产品推荐

