Javascript 为什么对象被认为是未定义的?
我试图在这个函数中获得一些位置坐标Javascript 为什么对象被认为是未定义的?,javascript,reactjs,Javascript,Reactjs,我试图在这个函数中获得一些位置坐标 getLocation(){ $.ajax({ url:"//freegeoip.net/json/?callback=?", dataType:'json', success:function (data) { this.setState({ coordinates:data },function () {
getLocation(){
$.ajax({
url:"//freegeoip.net/json/?callback=?",
dataType:'json',
success:function (data) {
this.setState({
coordinates:data
},function () {
console.log(this.state);
})
}.bind(this),
error:function (xhr,status,err) {
console.log(err);
}
})
}
我在componentWillMount()阶段调用它,并尝试填充此结构
this.state = {
restaurantsByLocations:{},
coordinates:{}
}
然而,当我试图将它传递给
getRestaurantsByLocation(lat,longi){
/**Some code here **/
}
它没有通过。在执行console.log()时,将填充我的对象。但是,在执行console.log(JSON.stringify(this.state.coordinates))时,它表明对象确实是空的
这是我的组件Willmount()
我可能错了,但是当您在ajax函数中使用this.state时,“this”是您的页面还是ajax调用 在getLocation()函数中,我将创建一个var
var\u this=this代码>
然后将其用作页面的参考:
_this.setState({
coordinates:data
},function () {
console.log(_this.state);
})
由于作用域的原因,AJAX调用中的此
没有引用您的组件。请尝试以下操作:
getLocation(){
var that = this;
$.ajax({
url:"//freegeoip.net/json/?callback=?",
dataType:'json',
success:function (data) {
that.setState({
coordinates:data
},function () {
console.log(this.state);
})
}.bind(this),
error:function (xhr,status,err) {
console.log(err);
}
})
}
通过这样做,您有效地创建了组件上下文的闭包,AJAX中的success
回调可以引用该闭包。因此,现在您应该能够毫无问题地设置状态
最后一件事是,使用React时,您可能还需要根据所使用的版本绑定上下文。我通常在构造函数中执行此操作,例如:
constructor(props) {
this.getLocation = this.getLocation.bind(this);
this.state = {coordinates: xyz};
}
getLocation
是异步的,JavaScript不会等到它完成后再转到getRestaurantsByLocation
调用
您可以将getRestaurantsByLocation
作为一个回调传递给fire,一旦它完成,就像这样
function getLocation(onLocationAvailable) {
$.ajax({
url: '/my/endpoint/',
success: function(data) {
onLocationAvailable(data.longitude, data.latitude);
}
});
}
getLocation(getRestaurantsByLocation);
然后像这样调用getLocation
function getLocation(onLocationAvailable) {
$.ajax({
url: '/my/endpoint/',
success: function(data) {
onLocationAvailable(data.longitude, data.latitude);
}
});
}
getLocation(getRestaurantsByLocation);
这意味着只有当数据从服务器返回时才会调用getRestaurantsByLocation
。当然,如果愿意,您仍然可以存储lat和long-in-state,然后调用回调,但我认为更清晰的方法是显式地传递它所需的数据。您应该做的是在setState
回调中调用getRestaurantsByLocation
函数。这样,您可以确保在调用函数时具有必要的信息,这与您的方法不同。看起来是这样的:
getLocation(){
$.ajax({
url:"//freegeoip.net/json/?callback=?",
dataType:'json',
success:function (data) {
this.setState({
coordinates:data
},function () {
this.getRestaurantsByLocation(data.latitude,data.longitude)
})
}.bind(this),
error:function (xhr,status,err) {
console.log(err);
}
})
}
这是一个异步调用,因此需要时间。当您执行console.log时,它会保留引用,以便在更改时可以看到它。当您执行stringify时,您将在给定的时间保留该值,并且您的状态尚未设置。编辑:您应该始终对ComponentDidMount执行异步调用,以便在更新状态时更新视图:您是否也可以在问题中添加调试控制台。日志s,包括其结果?感谢大家提供的解决方案!问题确实是异步调用,我将确保对自己进行更多的教育。再次感谢!但是他告诉我们他的console.log(this.state)
返回了预期的结果。意思是这不是问题所在?还是我遗漏了什么呢?这是意料之中的,而且很容易实现!我这边的马虎。