关于从 Slice 到 index.js 的响应数据的问题 - React redux 工具包

Problem about response data from Slice to index.js - React redux toolkit

我想从 API 获取数据并尝试在 index.js

中使用

错误:

TypeError: Cannot read properties of undefined (reading 'icon')

当我 console.log 它打印

Empty Array of index.js > response data of weatherSlice.js > and finally response data of index.js as an array

我遇到了未定义的错误并尝试了这个并且有点奏效。

{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>)}

Index.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 works/passes 因为 getCity.lengthundefined 并且 undefined !== 0 评估为真。在您开始访问状态后出现此问题。

获取的城市数据是具有 locationcurrentforecast 属性的对象。

// 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 aconditionproperty. When there isn't andgetCity.forecast.forecastday[1].condition` 是未定义,这是您看到的错误。

据我所知,condition 属性 嵌套在 day 字段中。由于不清楚响应数据中保证存在哪些属性,您最好的选择是:

  1. 首先确保您访问的路径正确
  2. 使用 null-checks/guard-clauses 或可选链接运算符来防止意外 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 : {},
},