Javascript 为什么在保存状态下存储OpenWeatherAPI获取的数据不会在React JS中呈现?
我一直在使用OpenWeather的Api获取数据,并将其存储到React JS中的已保存状态,以便调用已保存状态并在我的web应用程序上呈现实际的天气数据。问题是,我可以控制台记录存储在函数变量中的api数据,没有问题,我甚至可以将api数据直接传递到状态,然后再传递到我的web应用程序中。但是,当我尝试将api数据传递到变量中,然后将其保存到状态并呈现它时,我会得到一个错误“TypeError:无法获取未定义或空引用的属性'temp'。我不理解的原因是,如果我使用相同的“null reference”代码段,并尝试在函数中对其进行控制台日志记录,它将返回数据!我到底做错了什么 我对ReactJS还比较陌生,所以为了更好地理解ReactJS api调用,我阅读了Ethan Jerrel关于在React中获取api数据的文章(这篇文章确实帮了我很多忙): 以及之前关于类似问题的以下堆栈溢出问题: -基本开放天气api问题 -使用开放天气api的ajax调用存在问题 -使用api数据更新集合状态 这是我的代码:Javascript 为什么在保存状态下存储OpenWeatherAPI获取的数据不会在React JS中呈现?,javascript,reactjs,web,Javascript,Reactjs,Web,我一直在使用OpenWeather的Api获取数据,并将其存储到React JS中的已保存状态,以便调用已保存状态并在我的web应用程序上呈现实际的天气数据。问题是,我可以控制台记录存储在函数变量中的api数据,没有问题,我甚至可以将api数据直接传递到状态,然后再传递到我的web应用程序中。但是,当我尝试将api数据传递到变量中,然后将其保存到状态并呈现它时,我会得到一个错误“TypeError:无法获取未定义或空引用的属性'temp'。我不理解的原因是,如果我使用相同的“null refer
import React, { Component } from 'react';
// import logo from '../logo.svg';
import '../App.css';
class Main extends Component {
constructor(props) {
super(props);
this.state = {
kyoto: [],
kyotoMainWeather: [],
kyotoTemp: [],
kyotoDescription: [],
}
}
componentDidMount() {
this.fetchData();
}
fetchData(){
fetch('https://api.openweathermap.org/data/2.5/weather?q=kyoto&units=imperial&APPID=63dd0d75cb039f76bb9b092405a90895')
.then(response => response.json())
.then(data => {
console.log(data); //returns api data in object with no error
var kyoto = data; //stores api data in var
console.log(kyoto); // returns api data in object with no error
var kyotoMainWeather = data.weather[0].main; //stores api data in var
var kyotoTemp = data.main.temp; //stores api data in var
var kyotoDescription = data.weather[0].description; //stores api data in var
this.setState({kyoto: kyoto}); //stores api object data in saved state
this.setState({kyotoMainWeather: kyotoMainWeather}); //stores api object data in saved state
this.setState({kyotoTemp: kyotoTemp}); //stores api object data in saved state
this.setState({kyotoDescription: kyotoDescription}); //stores api object data in saved state
})
.catch(error => console.log('parsing failed', error))
}
render() {
return (
<div className="Body">
<div className="row">
<div className="col-sm-6">
<div className="card bg-dark text-white">
<img className="card-img" src={"https://images.pexels.com/photos/219000/pexels-photo-219000.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"} alt="Weather Card"/>
<div className="card-img-overlay d-flex align-items-end">
<div className="card-row">
<div className="temperature-city-container">
<h5 className="weather-card-text">{this.state.kyoto.main.temp}°</h5> // This is an actual data call which returns null in my web app, but when I console.log(kyoto.main.temp) it returns!
<p className="temperature-undertext">Kyoto, Japan</p>
</div>
<p className="weather-card-secondary-text">{this.state.kyotoTemp}</p> // this returns the data with no error
<p className="weather-card-secondary-text">{this.state.kyoto.main.temp}</p> // this is the same call (in theory) as the above "this.state.kyotoTemp" however it returns null, but when I console.log(kyoto.main.temp) it returns!
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Main;
import React,{Component}来自'React';
//从“../logo.svg”导入徽标;
导入“../App.css”;
类主扩展组件{
建造师(道具){
超级(道具);
此.state={
京都:[],
kyotoMainWeather:[],
kyotoTemp:[],
kyotoDescription:[],
}
}
componentDidMount(){
这是fetchData();
}
fetchData(){
取('https://api.openweathermap.org/data/2.5/weather?q=kyoto&units=imperial&APPID=63dd0d75cb039f76bb9b092405a90895')
.then(response=>response.json())
。然后(数据=>{
console.log(data);//返回对象中的api数据,没有错误
var kyoto=data;//在var中存储api数据
console.log(kyoto);//返回对象中的api数据,没有错误
var kyotamainweather=data.weather[0].main;//在var中存储api数据
var kyottemp=data.main.temp;//在var中存储api数据
var kyotoDescription=data.weather[0].description;//在var中存储api数据
this.setState({kyoto:kyoto});//以保存状态存储api对象数据
this.setState({kyotainweather:kyotainweather});//以保存状态存储api对象数据
this.setState({kyottemp:kyottemp});//以保存状态存储api对象数据
this.setState({kyotoDescription:kyotoDescription});//以保存状态存储api对象数据
})
.catch(错误=>console.log('解析失败',错误))
}
render(){
返回(
{this.state.kyoto.main.temp}°;//这是一个实际的数据调用,在我的web应用程序中返回null,但当我使用console.log(kyoto.main.temp)时,它返回null!
日本京都
{this.state.kyottemp}
//这将返回没有错误的数据
{this.state.kyoto.main.temp}
//这是与上面的“this.state.kyottemp”相同的调用(理论上),但是它返回null,但是当我控制台.log(kyoto.main.temp)返回时!
);
}
}
导出默认主;
看起来您是在提取数据之前渲染组件。尝试为传递给组件的数据提供默认值,或者在呈现之前检查数据是否存在。比如:
<h5 className="weather-card-text">
{this.state.kyoto && this.state.kyoto.main && this.state.kyoto.main.temp}°
</h5>
{this.state.kyoto&&this.state.kyoto.main&&this.state.kyoto.main.temp}°;
因此,在尝试从状态调用属性之前,请先检查状态是否存在
kyoto
,然后再检查kyto.main
。我刚刚尝试运行该属性,并收到相同的错误“TypeError:无法获取未定义或空引用的属性'temp'”,您的意思是运行某种if语句吗?{this.state.kyoto&&this.state.kyoto.main&&this.state.kyoto.main.temp}
?这是检查层次结构中每个父级的存在性,当它们都存在时返回true。这很有效!!!!非常感谢!!!这到底是如何工作的???为什么返回temp值?我没有看到“返回”语句,但它仍然返回它?这怎么可能?不客气!当查找深入树状结构的属性值时,通常必须检查是否存在中间节点。这就是为什么在(有争议的)中有一个更干净的方法。我的直接猜测是react在加载树中的每个步骤之前重新渲染特定组件,而您存储结果的变量在每次重新渲染时都已经有了这些数据。这很有意义!!您完全帮了我很多忙!非常感谢!!!