React Redux Toolkit 从Slice取数据渲染时报读取icon未定义错误如何解决
问题解决方法
问题根源
- 类型不匹配:weatherSlice初始状态中
item被设置为空数组,但接口返回的天气数据是对象类型,导致初始的getCity.length !== 0判断逻辑不可靠。当item被赋值为对象后,object.length为undefined,undefined !== 0判定为真,会提前触发渲染逻辑。 - 嵌套属性未做安全校验:直接访问
getCity.forecast.forecastday[1].condition.icon多层嵌套属性,中间任意一层属性为undefined都会触发报错,哪怕getCity本身有值,也可能存在forecast未定义、forecastday数组长度不足2、condition未定义的情况。
修复步骤
1. 修正Slice状态配置
对齐接口返回的数据类型,新增加载状态避免提前渲染:
export const weatherSlice = createSlice({ name: "weather", initialState : { item : {}, // 从空数组改为空对象,匹配接口返回的对象类型 loading: false, // 新增加载状态标记 }, reducers:{}, extraReducers:{ [fetchDefault.pending]: (state) => { state.loading = true }, [fetchDefault.fulfilled]: (state , action) => { state.loading = false state.item = action.payload; }, // 新增请求失败的状态处理,避免异常卡顿 [fetchDefault.rejected]: (state) => { state.loading = false } } })
2. 优化组件渲染逻辑
优先判断加载状态,嵌套属性使用可选链或者前置校验,避免访问不存在的属性:
首先在index.js中引入加载状态:
const dispatch = useDispatch(); const [selectedCity, setSelectedCity] = useState('Ankara'); const getCity = useSelector((state) => state.weather.item); const loading = useSelector((state) => state.weather.loading); // 新增加载状态取值 const [datee , setDate ] = useState(''); useEffect(() => { dispatch(fetchDefault(selectedCity)) setDate(getDate()) }, [dispatch, selectedCity]) // 补充selectedCity依赖,切换城市时会重新请求
渲染部分做安全校验:
// 加载过程中显示占位,不执行业务渲染逻辑 if(loading) return <div>天气数据加载中...</div> // 原基础信息渲染逻辑,用可选链做前置校验 {getCity?.current && ( <Typography variant="h6" component="div"> <div>Wind : {getCity.current.gust_kph} kph</div> <div>Pressure: {getCity.current.pressure_in} in</div> </Typography> )} // 预报模块渲染,提前校验forecastday长度至少为2,保证下标1的元素存在 {getCity?.forecast?.forecastday?.length >= 2 && ( <Grid item xs={3} sx={{mb:3}}> <div className="label">{getDate()}</div> <div className="label"> <img src={`${getCity.forecast.forecastday[1].condition.icon}`} alt="天气图标" /></div> <div className="label" >22 C</div> </Grid> )}
如果不想加额外的前置判断,也可以直接用可选链处理icon取值,写法更简洁:
<img src={`${getCity?.forecast?.forecastday?.[1]?.condition?.icon || ''}`} alt="天气图标" />
内容的提问来源于stack exchange,提问作者Fatih Can
相关产品推荐
相关产品推荐

