javascript - 关于从 Slice 到 index.js 的响应数据的问题 - React redux 工具包
问题描述
我想从 API 获取数据并尝试在 index.js 中使用
错误:
TypeError:无法读取未定义的属性(读取“图标”)
当我 console.log 它打印
index.js 的空数组 > weatherSlice.js 的响应数据 > 最后 index.js 的响应数据作为一个数组
我遇到了未定义的错误并尝试了这个并且有点工作。
{getCity.length !== 0 && (
<Typography variant="h6" component="div">
<div>Wind : {getCity.current.gust_kph} kph</div>
<div>Pressure: {getCity.current.pressure_in} in</div>
</Typography>
)}
但是这次它在这个块上给出了同样的错误
{getCity.length !== 0 && (
<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> // Gives undefined (reading"icon")
<div className="label" >22 C</div>
</Grid>)}
索引.js
const dispatch = useDispatch();
const [selectedCity, setSelectedCity] = useState('Ankara');
const getCity = useSelector((state) => state.weather.item);
const [datee , setDate ] = useState('');
useEffect(() => {
dispatch(fetchDefault(selectedCity))
setDate(getDate())
}, [dispatch])
天气切片
export const fetchDefault = createAsyncThunk('weather/getWeather', async (selectedCity) => {
const res = await axios(`http://api.weatherapi.com/v1/forecast.json?key=ebb6c0feefc646f6aa6124922211211&q=${selectedCity}&days=10&aqi=no&alerts=no
`)
return res.data});
export const weatherSlice = createSlice({
name: "weather",
initialState : {
item : [],
},
reducers:{},
extraReducers:{
[fetchDefault.fulfilled]: (state , action) => {
state.item = action.payload;
console.log(state.item)
},
[fetchDefault.pending]: (state , action) => {
console.log("sadsad")
}
}
解决方案
填充状态后,state.weather.item
它现在是一个对象,而不是数组。初始条件getCity.length !== 0
有效/通过,因为getCity.length
isundefined
并且undefined !== 0
评估为 true。在您开始访问该状态后会出现此问题。
获取的城市数据是一个具有location
、current
和forecast
属性的对象。
// 20211114135700
// https://api.weatherapi.com/v1/forecast.json?key=ebb6c0feefc646f6aa6124922211211&q=seattle&days=10&aqi=no&alerts=no
{
"location": {
"name": "Seattle",
"region": "Washington",
"country": "United States of America",
"lat": 47.61,
"lon": -122.33,
"tz_id": "America/Los_Angeles",
"localtime_epoch": 1636927019,
"localtime": "2021-11-14 13:56"
},
"current": {
"last_updated_epoch": 1636926300,
"last_updated": "2021-11-14 13:45",
"temp_c": 16.1,
"temp_f": 61.0,
"is_day": 1,
"condition": {
"text": "Light rain",
"icon": "//cdn.weatherapi.com/weather/64x64/day/296.png",
"code": 1183
},
"wind_mph": 13.6,
"wind_kph": 22.0,
"wind_degree": 190,
"wind_dir": "S",
"pressure_mb": 1014.0,
"pressure_in": 29.94,
"precip_mm": 1.0,
"precip_in": 0.04,
"humidity": 90,
"cloud": 100,
"feelslike_c": 16.1,
"feelslike_f": 61.0,
"vis_km": 3.2,
"vis_miles": 1.0,
"uv": 4.0,
"gust_mph": 18.8,
"gust_kph": 30.2
},
"forecast": {
"forecastday": [
{
"date": "2021-11-14",
"date_epoch": 1636848000,
"day": {
"maxtemp_c": 16.2,
"maxtemp_f": 61.2,
"mintemp_c": 11.5,
"mintemp_f": 52.7,
"avgtemp_c": 14.9,
"avgtemp_f": 58.8,
"maxwind_mph": 16.1,
"maxwind_kph": 25.9,
"totalprecip_mm": 21.1,
"totalprecip_in": 0.83,
"avgvis_km": 9.3,
"avgvis_miles": 5.0,
"avghumidity": 93.0,
"daily_will_it_rain": 1,
"daily_chance_of_rain": 99,
"daily_will_it_snow": 0,
"daily_chance_of_snow": 0,
"condition": {
"text": "Heavy rain",
"icon": "//cdn.weatherapi.com/weather/64x64/day/308.png",
"code": 1195
},
"uv": 1.0
},
"astro": {
...
},
"hour": [
...
]
},
...
]
}
}
您正在尝试渲染forecast
,但这是代码真正横向的地方。您假设至少有2 个元素(即 getCity.forecast.forecastday.length>= 2), and then if there is, assume theres a
条件property. When there isn't and
getCity.forecast.forecastday[1].condition` 未定义,这是您看到的错误。
据我所知,该condition
属性嵌套在一个day
字段中。由于尚不清楚响应数据中保证存在哪些属性,因此最好的选择是:
- 首先确保您访问的是正确的路径
- 使用 null-checks/guard-clauses 或 Optional Chaining operator 来防止意外的 null/undefined 访问
更新后的对象属性路径如下:
getCity.forecast.forecastday.[1].day.condition.icon
如果其中任何一个可能未定义或未在数据中返回,则使用可选链接运算符的更正访问如下:
getCity.forecast?.forecastday?.[1]?.day?.condition?.icon
这是等效的 null-check/guard-clause 版本:
getCity.forecast
&& getCity.forecast.forecastday
&& getCity.forecast.forecastday[1]
&& getCity.forecast.forecastday[1].day
&& getCity.forecast.forecastday[1].day.condition
&& getCity.forecast.forecastday[1].day.condition.icon
current
对天气数据使用相同类型的检查:
{getCity.current && (
<Typography variant="h6" component="div">
<div>Wind : {getCity.current.gust_kph} kph</div>
<div>Pressure: {getCity.current.pressure_in} in</div>
</Typography>
)}
最后,更新天气切片的初始状态以匹配数据不变量,它应该是一个对象。
initialState : {
item : {},
},
推荐阅读
- javascript - 为什么即使我通过了身份验证,我也能够重定向回登录组件?
- python - 如何在不打开spotfire的情况下仅使用脚本将链接数据保存为嵌入数据?
- vue.js - nuxt如何在页面名称后加问号
- arrays - 如何使用 RGB 值正确创建图像周围的轮廓?
- react-native - 打字稿中的反应警告“无法对未安装的组件执行反应状态更新。”
- tensorflow - TensorFlow initial_weights 是什么意思?
- c - GCC 标头 - 他们解决什么问题?
- visual-studio-code - 在多文件夹workspaceFolder变量中嵌套/加入工作区输入变量?
- python - MongoDB 上的 Docker-compose
- php - Vue.prototype.$appName 动态改变值