获取地理位置并在componentDidMount()中发送Ajax请求

问题描述 投票:1回答:1

我正在尝试使用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)
        })
    }

我对一切运行方式的理解如下:

  1. 初始组件呈现
  2. 调用componentDidMount()并查看if语句
  3. 找不到URI属性,所以启动getCurrentPosition()调用,使用新的URI属性设置状态(据我所知,this.setState应该触发重新渲染,然后......)
  4. componentDidMount()再次运行,但这次找到了URI属性
  5. 由于某种未知原因,fetch()没有运行

虽然我不确定,但我最好的猜测是虽然现在有了URI属性,但是当新的componentDidMount()运行时,程序仍处于确定将其设置为的过程中。但我可能完全错了。我还可以创建一个无限循环,其中componentDidMount()永远不会看到URI属性并不断重新渲染。

javascript reactjs asynchronous fetch-api
1个回答
1
投票

正如@brub所说:无论ui更新多少,componentDidMount都不会运行多次。我最终使用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))
    }
© www.soinside.com 2019 - 2024. All rights reserved.