React.js调用openweatherAPI时无法从对象数组读取main.temp报错
问题根因
报错是组件首次渲染时异步请求尚未完成导致:
- Redux的weather模块初始状态中,
item字段默认是空对象/null/undefined - 组件第一次挂载渲染时,
fetchDefault请求还处于pending状态,extraReducers的fulfilled回调尚未执行,state.weather.item还没有被赋值为接口返回的完整数据 - 此时直接访问
getCity.main.temp,因为getCity初始没有main属性,getCity.main为undefined,读取undefined的temp属性就会触发类型错误。
解决方案
以下三种常用方案按需选择即可:
方式1:使用可选链运算符兜底
直接修改组件内的取值写法,自动判断上层属性是否存在:
{getCity?.main?.temp}
如果getCity或main不存在,表达式会直接返回undefined不会抛出错误,等请求完成、数据更新后会自动重新渲染显示温度值。
方式2:添加条件渲染判断
在渲染温度前先判断main属性是否存在:
const getCity = useSelector((state) => state.weather.item); // 写法1:短路判断 {getCity.main && getCity.main.temp} // 写法2:完整分支,可搭配加载提示 {getCity.main ? ( <span>{getCity.main.temp}</span> ) : ( <span>温度加载中...</span> )}
方式3:完善Redux初始状态结构
给weather模块的item设置符合接口结构的初始默认值,从根源避免属性读取报错:
// 定义weather slice的初始状态时配置如下结构 const initialState = { item: { main: {}, name: '' // 其他需要用到的字段都可以提前设置对应类型的初始值 }, // 其他状态字段,比如loading、error等 }
补充优化建议:可以在weather slice中新增
loading状态,在fetchDefault.pending时设loading: true,fulfilled/rejected时设为false,组件内先判断loading状态,加载中时显示统一的占位符,加载完成后再渲染具体数据,使用体验更好。
内容的提问来源于stack exchange,提问作者Suat Süleyman KÜSKÜ
相关产品推荐
相关产品推荐

