在 componentDidMount() 中获取地理位置并发送 Ajax 请求
Getting geolocation and Sending an Ajax Request in componentDidMount()
我正在尝试使用 navigator.geolocation.getCurrentPosition()
从用户计算机接收到的坐标调用天气 API
我的问题是,鉴于一切都是 运行 异步的,我无法找出正确的方法来执行此操作。然后,我想我想出了一个使用 componentDidMount() 的不错的解决方法,但不幸的是它没有用。
这是我的 codepen(没有 API 密钥)
这是代码:
state = {
data: "Please wait while you're weather is loading...",
}
componentDidMount() {
this.state.hasOwnProperty('uri') ?
fetch(this.state.uri).then((res) => res.json())
.then((data) => this.setState({
data: {
tempString: data.current_observation.temperature_string,
realTemp: data.current_observation.feelslike_string,
skyImg: data.current_observation.icon_url.substring(0, 4) + 's' + data.current_observation.icon_url.substring(4),
location: data.current_observation.display_location.full,
temp_f: data.current_observation.temp_f,
}
}))
.catch((err) => console.log(err.message))
: navigator.geolocation.getCurrentPosition((pos) => {
this.setState({
uri: "https://api.wunderground.com/api/{API GOES HERE}/conditions/q/" + pos.coords.latitude.toString() + "," + pos.coords.longitude.toString() + ".json"
})
console.log(this.state.uri)
})
}
我对一切的理解运行如下:
- 初始组件呈现
- componentDidMount()被调用并查看if语句
- 找不到 URI 属性,因此启动 getCurrentPosition() 调用,使用新的 URI 属性 设置状态(据我所知,this.setState 应该触发重新-渲染,然后...)
- componentDidMount() 再次运行,但这次找到了 URI 属性
- 由于某些未知原因,fetch() 不是 运行
虽然我不确定,但我最好的猜测是虽然现在有 URI 属性,但到新的 componentDidMount() 运行时,程序仍在确定要设置它的内容作为。但我可能完全错了。我还可以创建一个无限循环,其中 componentDidMount() 永远不会看到 URI 属性 并不断重新呈现。
正如@brub 所说:componentDidMount 不会 运行 多次,无论 ui 更新了多少。我最终使用 componentDidUpdate 作为解决方案。现在是代码:
state = {
data: "Please wait while you're weather is loading...",
}
componentDidMount() {
navigator.geolocation.getCurrentPosition((pos) => {
this.setState({
uri: "https://api.wunderground.com/api/{API GOES HERE}/conditions/q/" + pos.coords.latitude.toString() + "," + pos.coords.longitude.toString() + ".json"
})
})
}
componentDidUpdate() {
fetch(this.state.uri).then((res) => res.json())
.then((data) => this.setState({
data: {
tempString: data.current_observation.temperature_string,
realTemp: data.current_observation.feelslike_string,
skyImg: data.current_observation.icon_url.substring(0, 4) + 's' + data.current_observation.icon_url.substring(4),
location: data.current_observation.display_location.full,
temp_f: data.current_observation.temp_f,
}
}))
.catch((err) => console.log(err.message))
}
我正在尝试使用 navigator.geolocation.getCurrentPosition()
从用户计算机接收到的坐标调用天气 API我的问题是,鉴于一切都是 运行 异步的,我无法找出正确的方法来执行此操作。然后,我想我想出了一个使用 componentDidMount() 的不错的解决方法,但不幸的是它没有用。
这是我的 codepen(没有 API 密钥)
这是代码:
state = {
data: "Please wait while you're weather is loading...",
}
componentDidMount() {
this.state.hasOwnProperty('uri') ?
fetch(this.state.uri).then((res) => res.json())
.then((data) => this.setState({
data: {
tempString: data.current_observation.temperature_string,
realTemp: data.current_observation.feelslike_string,
skyImg: data.current_observation.icon_url.substring(0, 4) + 's' + data.current_observation.icon_url.substring(4),
location: data.current_observation.display_location.full,
temp_f: data.current_observation.temp_f,
}
}))
.catch((err) => console.log(err.message))
: navigator.geolocation.getCurrentPosition((pos) => {
this.setState({
uri: "https://api.wunderground.com/api/{API GOES HERE}/conditions/q/" + pos.coords.latitude.toString() + "," + pos.coords.longitude.toString() + ".json"
})
console.log(this.state.uri)
})
}
我对一切的理解运行如下:
- 初始组件呈现
- componentDidMount()被调用并查看if语句
- 找不到 URI 属性,因此启动 getCurrentPosition() 调用,使用新的 URI 属性 设置状态(据我所知,this.setState 应该触发重新-渲染,然后...)
- componentDidMount() 再次运行,但这次找到了 URI 属性
- 由于某些未知原因,fetch() 不是 运行
虽然我不确定,但我最好的猜测是虽然现在有 URI 属性,但到新的 componentDidMount() 运行时,程序仍在确定要设置它的内容作为。但我可能完全错了。我还可以创建一个无限循环,其中 componentDidMount() 永远不会看到 URI 属性 并不断重新呈现。
正如@brub 所说:componentDidMount 不会 运行 多次,无论 ui 更新了多少。我最终使用 componentDidUpdate 作为解决方案。现在是代码:
state = {
data: "Please wait while you're weather is loading...",
}
componentDidMount() {
navigator.geolocation.getCurrentPosition((pos) => {
this.setState({
uri: "https://api.wunderground.com/api/{API GOES HERE}/conditions/q/" + pos.coords.latitude.toString() + "," + pos.coords.longitude.toString() + ".json"
})
})
}
componentDidUpdate() {
fetch(this.state.uri).then((res) => res.json())
.then((data) => this.setState({
data: {
tempString: data.current_observation.temperature_string,
realTemp: data.current_observation.feelslike_string,
skyImg: data.current_observation.icon_url.substring(0, 4) + 's' + data.current_observation.icon_url.substring(4),
location: data.current_observation.display_location.full,
temp_f: data.current_observation.temp_f,
}
}))
.catch((err) => console.log(err.message))
}