Javascript 为什么在保存状态下存储OpenWeatherAPI获取的数据不会在React JS中呈现?

Javascript 为什么在保存状态下存储OpenWeatherAPI获取的数据不会在React JS中呈现?,javascript,reactjs,web,Javascript,Reactjs,Web,我一直在使用OpenWeather的Api获取数据,并将其存储到React JS中的已保存状态,以便调用已保存状态并在我的web应用程序上呈现实际的天气数据。问题是,我可以控制台记录存储在函数变量中的api数据,没有问题,我甚至可以将api数据直接传递到状态,然后再传递到我的web应用程序中。但是,当我尝试将api数据传递到变量中,然后将其保存到状态并呈现它时,我会得到一个错误“TypeError:无法获取未定义或空引用的属性'temp'。我不理解的原因是,如果我使用相同的“null refer

我一直在使用OpenWeather的Api获取数据,并将其存储到React JS中的已保存状态,以便调用已保存状态并在我的web应用程序上呈现实际的天气数据。问题是,我可以控制台记录存储在函数变量中的api数据,没有问题,我甚至可以将api数据直接传递到状态,然后再传递到我的web应用程序中。但是,当我尝试将api数据传递到变量中,然后将其保存到状态并呈现它时,我会得到一个错误“TypeError:无法获取未定义或空引用的属性'temp'。我不理解的原因是,如果我使用相同的“null reference”代码段,并尝试在函数中对其进行控制台日志记录,它将返回数据!我到底做错了什么

我对ReactJS还比较陌生,所以为了更好地理解ReactJS api调用,我阅读了Ethan Jerrel关于在React中获取api数据的文章(这篇文章确实帮了我很多忙):

以及之前关于类似问题的以下堆栈溢出问题:

-基本开放天气api问题

-使用开放天气api的ajax调用存在问题

-使用api数据更新集合状态

这是我的代码:

   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}&#176;</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}&#176;
</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在加载树中的每个步骤之前重新渲染特定组件,而您存储结果的变量在每次重新渲染时都已经有了这些数据。这很有意义!!您完全帮了我很多忙!非常感谢!!!