为什么对象出现未定义?

时间:2017-06-02 15:19:07

标签: javascript reactjs

我想在这个函数中找到一些位置坐标

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))时,它显示该对象确实是空的。

这是我的componentWillMount()

componentWillMount(){

this.getLocation();
this.getRestaurantsByLocation(this.state.coordinates.latitude,this.state.coordinates.longitude)


}

4 个答案:

答案 0 :(得分:2)

您应该在getRestaurantsByLocation回调中拨打setState功能。这样,您可以确保在调用函数时获得必要的信息,这与您的方法不同。看起来像这样:

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);
        }
    })
}

答案 1 :(得分:1)

alloca是异步的,JavaScript在进入getLocation调用之前不会等待它完成。

你可以将getRestaurantsByLocation作为回调传递给它,一旦它完成,就像这样......

getRestaurantsByLocation

然后像这样打电话给function getLocation(onLocationAvailable) { $.ajax({ url: '/my/endpoint/', success: function(data) { onLocationAvailable(data.longitude, data.latitude); } }); } ......

getLocation

这意味着只有在数据从服务器返回后才会调用getLocation(getRestaurantsByLocation); 。当然,如果你愿意,你仍然可以存储lat和long in状态然后调用回调,但我认为更明确地传递它所需的数据。

答案 2 :(得分:0)

我可能错了,但是当你在ajax函数中使用this.state时,'this'是你的页面还是ajax调用?

在你的getLocation()函数中,我会创建一个var var _this = this;

然后将其用作页面的参考:

_this.setState({
   coordinates:data
},function () {
   console.log(_this.state);
})

答案 3 :(得分:0)

由于范围界定,AJAX调用中的

this未引用您的组件。请尝试以下方法:

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回调可以引用的组件上下文的闭包。所以现在你应该能够setState没有问题。

最后一件事,使用React,您可能还需要根据您使用的版本绑定上下文。我通常在构造函数中执行此操作,例如:

constructor(props) {
  this.getLocation = this.getLocation.bind(this);
  this.state = {coordinates: xyz};
}