2017-06-02 111 views
0

我试图得到一些位置坐标在此功能为什么对象未定义?

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

这是一个异步调用,所以需要时间。当你使用console.log时,它会在引用发生变化时保持引用,你会看到它。当你进行串联化时,你在这个给定的时间保持这个值,并且你的状态还没有设置。编辑:你应该总是在ComponentDidMount上进行异步调用,以便在更新状态时更新视图:https://facebook.github.io/react/docs/react-component.html#componentdidmount – Nevosis

+0

你还可以添加你的调试' console.log的问题,包括他们的结果? –

+0

谢谢大家的解决方案!这个问题确实是异步调用,我会确保更多地教育自己。再次感谢! – LoXatoR

回答

2

你应该做的是在你的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); 
     } 
    }) 
} 
+0

谢谢,这按预期工作,很容易实现!马虎从我身边。 – LoXatoR

0

我可能是错的,但是当你使用this.state在你的Ajax功能,是“这”是你的页面或Ajax调用?

在你的getLocation()函数,我想创建一个变种var _this = this;

然后用它作为你的页面的引用:

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

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

最后一件事情,对于React,您可能还需要绑定上下文,具体取决于您使用的是哪个版本。我通常做在我的构造函数,例如:

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

但他告诉我们他的'console.log(this.state)'返回了预期的结果。这意味着这不是问题吗?或者我错过了一些东西 – DrunkDevKek

1

getLocation是异步的,JavaScript的不会等待它完成它移动到getRestaurantsByLocation调用之前。

你可以通过getRestaurantsByLocation作为回调火一旦它虽然完成,这样的事情...

function getLocation(onLocationAvailable) { 
    $.ajax({ 
     url: '/my/endpoint/', 
     success: function(data) { 
      onLocationAvailable(data.longitude, data.latitude); 
     } 
    }); 
} 

然后调用getLocation这样的...

getLocation(getRestaurantsByLocation); 

这将意味着只有在数据从服务器返回时才会调用getRestaurantsByLocation。当然,如果你愿意,你仍然可以存储经纬度,然后调用回调函数,但我认为它明确地传递它需要的数据。