ReactNative GeoLocation 与另一个异步 api 调用内部不起作用



我正在使用地理位置来获取当前坐标(纬度和经度)。当坐标可用时,我希望能够使用返回的坐标进行 API 调用。 但是,由于某种原因,API 调用未正确执行。在地理位置返回坐标后立即进行 API 调用的正确方法是什么? 这是代码:

const that = this;
//Getting the current location using the geolocation API
navigator.geolocation.getCurrentPosition(
(position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null
});

//Here is the API call to be executed after the coordinates are returned and state is set for the latitude and longitude
const url = 'http://sewoa-easy-breezy-home-number-api-us1.smx.online/api/v1/houses/number?latitude=' + that.state.latitude
+ '&longitude=' + that.state.longitude;
axios.get(url).then(function (response) {
if (response.data) {
Actions.viewHouseNumber({ houseNumber: response.data.number });
} else {
Actions.houseNotFound({ latitude: that.state.latitude, longitude: that.state.longitude });
}
}).catch(() => {
// The request was made, but the server responded with a status code
// that falls out of the range of 2xx
if (that.state.latitude && that.state.longitude) {
Actions.houseNotFound({ latitude: that.state.latitude, longitude: that.state.longitude });
}
else {
Actions.error({ message: 'connection_error'});
}
});
},
(error) => {
Actions.error({ message: 'gps_error' });
return;
},
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
) 

这里使用的navigation.getCurrentPostion和axios.get方法都分别工作。但是,现在 API 调用在 gelocation.getCurrentPosition 方法中,整个事情都不起作用。关于我如何解决这个问题的任何想法?

在 React 中,setState 是异步的。这意味着它不会立即执行,它将等到下一个更新周期才能实际执行。这通常对用户不可见,但这意味着that.state.latitudethat.state.longitude可能未定义。在 setState 调用后立即尝试console.log(that.state.latitude, that.state.longitude)

解决方案:setState接受回调作为第二个参数。您可以将依赖于状态新值的所有代码部分放在所述回调中。这将确保在运行这些行之前已更新状态。

这可能看起来像这样(假设您发布的代码段位于组件的组件 WillMount 方法中):

class MyComponent extends Component {
fetchHouseNumber = () => {
const url = 'http://sewoa-easy-breezy-home-number-api-us1.smx.online/api/v1/houses/number?latitude=' + this.state.latitude
+ '&longitude=' + this.state.longitude;
axios.get(url).then(function (response) {
if (response.data) {
Actions.viewHouseNumber({ houseNumber: response.data.number });
} else {
Actions.houseNotFound({ latitude: this.state.latitude, longitude: this.state.longitude });
}
}
componentWillMount() {
//Getting the current location using the geolocation API
navigator.geolocation.getCurrentPosition(
(position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null,
}, () => this.fetchHouseNumber()); // The callback I'm talking about
}
(error) => {
Actions.error({ message: 'gps_error' });
},
{
enableHighAccuracy: true,
timeout: 20000,
maximumAge: 1000
})
}
}

旁注:你为什么使用that而不是这个?由于您正在使用箭头函数,因此无需保护this的值。另外,我没有在您的代码片段中看到that被分配。你的问题不能来自这个吗?

编辑:性能

正如评论中所指出的,在setState上使用回调可能会很昂贵。如果你想尽快触发你的API调用,在等待setState回调被触发之前,你可以这样做:

class MyComponent extends Component {
fetchHouseNumber = (latitude, longitude) => {
const url = 'http://sewoa-easy-breezy-home-number-api-us1.smx.online/api/v1/houses/number?latitude=' + latitude
+ '&longitude=' + longitude;
axios.get(url).then(function (response) {
if (response.data) {
Actions.viewHouseNumber({ houseNumber: response.data.number });
} else {
Actions.houseNotFound({ latitude, longitude });
}
}
componentWillMount() {
//Getting the current location using the geolocation API
navigator.geolocation.getCurrentPosition(
(position) => {
const { latitude, longitude } = position.coords; // destructuring assignment
this.fetchHouseNumber(latitude, longitude);
this.setState({
latitude, // object property shorthand
longitude,
error: null
});
}
(error) => {
Actions.error({ message: 'gps_error' });
},
{
enableHighAccuracy: true,
timeout: 20000,
maximumAge: 1000
})
}
}

这样,一旦地理位置数据可用,您就会触发回调,但如果地理位置数据在组件中的其他地方需要,则仍然将地理位置数据置于状态(如果不是,您可以删除 setState 部分......

最新更新