编辑:所以我遇到了一些堆栈溢出的麻烦,不得不重新输入一些东西....包括Weather weatherData = {this.state.weatherData}我在这里不小心输错了天气weatherData = {weatherData}。但我也在我的代码上输入了错误,那就是setState。我是新的reactjs和一些我发现很奇怪的语法,所以这可能是我有语法错误的原因。所以我最终修复了一些东西,但仍然有一个错误“this.setState不是一个函数”。我想也许这是一个范围问题,所以我创建了一个新方法updateWeatherData,并且有效。
所以我想制作一个天气应用程序。我想要做的是在this.state.weatherData中有数据后加载名为Weather的子组件。我已经使用console.log进行了检查,数据是从ajax调用回来的,但我似乎无法设置它。我得到的错误信息是“无法读取未定义的属性'weatherData'”
var React = require('react');
var Weather = require('./Weather');
class App extends React.Component{
constructor(props)
{
super(props);
this.state = {
weatherData: null,
};
this.getDataFromLatLng = this.getDataFromLatLng.bind(this);
this.showPosition = this.showPosition.bind(this);
}
updateWeatherData (results)
{
this.setState({
weatherData:results
});
}
componentDidMount()
{
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(this.showPosition);
} else {
alert("Geolocation is not supported by this browser.");
}
}
showPosition(position)
{
this.getDataFromLatLng(position.coords.latitude, position.coords.longitude);
}
getDataFromLatLng(lat, lng)
{
$.ajax({
url: 'http://api.openweathermap.org/data/2.5/weather?lat='+lat+'&lon='+lng+"&units=metric&appid=ID",
type:"GET",
dataType:"jsonp",
//CHANGED FROM THIS:
/*success:function(results){
//RESULTS COME BACK
console.log(results);
this.setState=({
weatherData:results
});
console.log(this.state.weatherData);
//But no weatherData is being set
},*/
//TO THIS:
success:this.updateWeatherData,
error: function(xhr, status, error) {
console.log(xhr.responseText + " " + status, " " + error);
}
});
}
render()
{
return(
<div id="container">
Hello From App
{this.state.weatherData != null
? <Weather weatherData={this.state.weatherData}/>
: <p>Loading...</p>
}
</div>
);
}
}
module.exports = App;
答案 0 :(得分:2)
将<Weather weatherData={weatherData}/>
更改为<Weather weatherData={this.state.weatherData}/>
关于为什么console.log(this.state.weatherData)
没有显示您设置的值,这是因为setState
是异步的。请参阅this article。
具体来说,我指的是文章中的以下几行:
// assuming this.state = { value: 0 }
this.setState({
value: 1
});
console.log(this.state.value); // 0
答案 1 :(得分:0)
<div id="container">
Hello From App
{this.state.weatherData != null
? <Weather weatherData={weatherData}/>
: <p>Loading...</p>
}
</div>
这里如果你看到你的代码,你想要它渲染一次this.state.weatherData有一些东西。所以我们说它已经有了,现在是时候渲染了。你正在渲染的组件正在被赋予道具作为weatherData ...但你没有在任何地方定义它。你真的想要通过
的状态 <div id="container">
Hello From App
{this.state.weatherData != null
? <Weather weatherData={this.state.weatherData}/>
: <p>Loading...</p>
}
</div>
因为
而无法看到它 //RESULTS COME BACK
console.log(results);
this.setState=({
weatherData:results
});
console.log(this.state.weatherData);
//But no weatherData is being set
结果来了,你setState结果。然而,这不是一个你可以设置值的对象..它将被调用,反应将做它的事情并更新状态但它不会在继续前进之前完成它。它只是向前移动并在后台异步进行。一旦getDataFromLatLng完成,将调用渲染,你应该总是在render方法中检查更新的状态..
render(){
console.log(this.state.weatherData);
// Your Code here
}
您将在那里看到更新后的状态。 至于你在哪里传递道具作为weatherData而不是this.state.weatherData,如果你打算在渲染中使用它,就像你使用两次一样。如果你愿意,可以这样使用它。这称为Object destructuring
render(){
const {weatherData} = this.state ;
return(
<div id="container">
Hello From App
{weatherData != null
? <Weather weatherData={weatherData}/>
: <p>Loading...</p>
}
</div>
);
}
您现在可以使用weatherData而不是this.state.weatherData。我们在这里使用const来声明因为状态是不可变的,所以你不要错误地在渲染中改变它。