You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 02:15:09