React中如何将异步获取的对象作为props传递?
问题原因
你的报错本质是首次渲染时异步请求还未完成,初始状态是空对象,访问不存在的深层属性导致报错:
- 组件初始化时
data的初始值是{},此时data.event1为undefined - 你直接访问
data.event1.date相当于读取undefined.date,直接抛出类型错误 - 后续异步请求完成更新
data后,页面能正常渲染;刷新后又会回到初始化状态,所以重复报错
解决方法
你可以根据场景选择下面任意一种方案:
方案1:使用可选链操作符(最简便)
直接用ES6+的可选链?.访问深层属性,当前面的属性不存在时会直接返回undefined,不会抛出错误:
<TrainingSchedule date={data.event1?.date} // 把原来的写法改成这样即可 month='SEPT' eventTitle='Lets Get to know each other' eventDescription='Have a drink with our finest coach and enjoy the summer' time='1pm' backgroundColor= 'CadetBlue' />
方案2:新增加载状态控制渲染
新增一个loading状态,数据拉取完成前渲染加载占位符,避免未就绪时访问数据:
// 新增loading state const [loading, setLoading] = useState(true); const [data, setData] = useState({}); const fetchData =async () => { const docRef = doc(db, "data", "RSVp8ljO95Dpwa0oSs0G"); const docSnap = await getDoc(docRef); const dataTest = docSnap.data(); setData(dataTest); // 注意:setData不需要加await,原生React的状态更新函数不是异步函数 setLoading(false); // 数据更新完成后关闭加载状态 console.log("Document data:", dataTest); } useEffect(() => { fetchData(); }, []) // 渲染时先判断loading状态 if(loading) return <div>加载中...</div> return ( // 保留原来的渲染逻辑即可,此时data已经有完整数据 )
方案3:给初始状态设置默认结构
直接给state的初始值补全嵌套结构,避免初始访问时报错:
// 初始值里提前补上event1的空对象,这样初始访问data.event1.date不会报错 const [data, setData] = useState({ event1: {} });
内容的提问来源于stack exchange,提问作者Juls
相关产品推荐
相关产品推荐

