类型错误: 无法读取未定义数据的属性'0'提取



我对reactjs很不了解,我正在制作我在天气预报APP上的第二个项目。每当我想要获得存储在weatherList中的数据时,我都会出错。这就是为什么"TypeError:无法读取未定义数据的属性'0' .

请给我正确的建议,我应该使用,以避免这个错误。

以下是我的App.js代码:

import React, { useEffect, useState} from "react";
import './App.css';
import SearchBar from './components/SearchBar/SearchBar';
import WeatherBox from './components/WeatherCard/WeatherBody';
import { Grid } from "@material-ui/core";
import { makeStyles } from '@material-ui/core/styles';
require('dotenv').config();  

const useStyles = makeStyles({
root: {
minWidth: 275,
backgroundColor: '#091f43',
color: 'var(--text_light)',
margin: 'auto'
},
inputs: {
border: 'none',
background: 'none',
outline: 'none',
color: 'inherit',
fontSize: '2rem',
height: '40px',
padding: '5px 5px 10px',
borderBottom: '1px solid'
},
buttons: {
border: 'none',
outline: 'none',
color: 'inherit',
fontSize: '1rem',
fontWeight: 'bold',
letterSpacing: '0.1em',
padding: '15px 20px',
marginLeft: '15px',
borderRadius: '5px',
backgroundColor: 'red',
transition: 'background 0.3s ease-in-out',
cursor:'pointer'
},
formStyling: {
position: 'relative',
display: 'flex',
alignItems: 'center',
},
headings: {
fontWeight: 'bold',
fontSize: '4rem',
letterSpacing: '0.02em',
padding: '0 0 30px 0'
}
});

const API_KEY = process.env.REACT_APP_BART_API_KEY;
function App() {
const [city, setCity] = useState(null);
const [responseData, setresponseData] = useState(null);
const [searches, setSearches] = useState(null);
const [weatherList, setweatherList] = useState([]);
const [date, setdate] = useState(null);
// const [buttonClick, setButtonClick] = useState(false);
const classes = useStyles();
const isRowBased = window.matchMedia('(min-width: 700px)');
useEffect( () => {
const fetchApi = async () => {
const url = `https://api.openweathermap.org/data/2.5/forecast?q=${searches}&appid=${API_KEY}`;
const response = await fetch(url);
// console.log(response);
const resJson = await response.json();
setresponseData(resJson);
setweatherList(resJson.list);
};
fetchApi();
}, [searches])

function dataExtracting()
{
var dates = weatherList[0].dt_txt;
setdate(dates);
}
function handleChange(event) {
const cityName = event.target.value;
setCity(cityName);
}
function submitCity(event) {
setSearches(city);
dataExtracting();

// setButtonClick(true);
// setTimeout( () => setButtonClick(false), 2000);
event.preventDefault();
}
return (
<div className="App">
<Grid className={classes.root} sm={6}>
<h1 className={classes.headings}>Weather Forcast App</h1>
<form className={classes.formStyling} style={styles.container(isRowBased)}>
<input onChange={handleChange} className={classes.inputs} style={styles.containerInput(isRowBased)} type="text" placeholder="Search for a city" autoFocus />
</form>
<button className={classes.buttons} style={styles.containerButton(isRowBased)} type="submit" onClick={submitCity}>Search</button>
<span class="msg"></span>

</Grid>
<WeatherBox />    
</div>
);
}
const styles = {
container: isRowBased => ({
flexDirection: 'column',
width: '100%'
}),
containerInput: isRowBased=> ({
width: '100%'
}),
containerButton: isRowBased => ({
margin: '20px 0 0 0',
width: '100%'
})
};
export default App;

这是错误我得到:-

TypeError: Cannot read property '0' of undefined
dataExtracting
P:/Web Dev/Weather-Application-Reactjs/weatherapp/src/App.js:87
84 | 
85 | function dataExtracting()
86 | {
> 87 |   var dates = weatherList[0].dt_txt;
| ^  88 |   setdate(dates);
89 | }
90 | function handleChange(event) {

编辑

我已经检查了chrome检查中的状态,我看到我想要保存在weatherList中的数据被保存而没有任何错误,但我无法通过dataextraction()函数访问它。实际上,我需要从响应中获取列表,然后提取5天的天气数据以显示在web应用程序中。为此,我使用dataextraction()函数,该函数在submitCity()函数中被调用。添加函数后,我只得到这个错误。这个编辑是为了澄清API调用没有问题,我已经检查了很多次。

我想知道您是否试图在正确填充之前访问列表。我的意思是,你在useEffect中的初始API调用应该返回一个错误,因为它看起来像这样:

useEffect( () => {
const fetchApi = async () => {
const url = `https://api.openweathermap.org/data/2.5/forecast?q=null&appid=<YOUR_KEY>`;
const response = await fetch(url);
// console.log(response);
const resJson = await response.json();
setresponseData(resJson);
setweatherList(resJson.list);
};

当我使用我的API密钥执行此测试时,我的响应是:

{
"cod": "404",
"message": "city not found"
}

由于您将城市的初始状态设置为null,因此第一次传递不应该提供任何数据,这将解释为什么您的天气列表是undefined。我唯一的想法是,在您试图访问dataExtracting()函数中的搜索列表之前,您的submitCity函数没有完成setSearches并完成fetchApi调用。由于您需要使用新城市更新状态,然后输入async函数并等待响应,等待转换,然后在输入dataextraction函数之前设置列表,因此我认为这可能是问题所在。

可能有效的几个解决方案是:在你的useEffect中添加一个检查,看看是否有一个列表。如果有,立即提取数据并执行setdate。我不喜欢这个解决方案,但我认为它应该有效:

useEffect( () => {
const fetchApi = async () => {
const url = `https://api.openweathermap.org/data/2.5/forecast?q=${searches}&appid=5b451f60067d169e5b9acb877efadcda`;
const response = await fetch(url);
// console.log(response);
const resJson = await response.json();
setresponseData(resJson);
setweatherList(resJson.list);
if (resJson.list && resJson.list.length) {
setdate(resJson.list[0].dt_txt);
}
};

如果你在useEffect中执行weatherList的检查,那么你可以分离设置搜索和提取submitCity内部日期的逻辑(如果你确实将其添加到useEffect中,你将从submitCity中删除dataExtraction调用)。我还没有测试过这种方法,但我怀疑这种事件顺序是给您带来问题的原因。此外,可能值得考虑添加对有效城市输入的检查,或者甚至可以将输入转换为有效城市的下拉列表,以帮助实现数据完整性。我可以预见到拼错的城市等,否则会导致未来的问题。

您是否可以通过放置控制台resJson来检查。列表是数据是否存在。你应该试试

var dates = responseData[0].dt_txt;
setdate(dates);

最新更新