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

Posted

技术标签:

【中文标题】在 componentDidMount() 中获取地理位置并发送 Ajax 请求【英文标题】:Getting geolocation and Sending an Ajax Request in componentDidMount() 【发布时间】:2018-06-11 05:17:14 【问题描述】:

我正在尝试使用 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 属性并不断重新渲染。

【问题讨论】:

为什么 componentDidMount 会运行多次?它只运行一次,当组件被挂载时。 谢谢!我完全忽略了 componentDidMount 在初始安装时的事实,而不是在重新渲染时。 【参考方案1】:

正如@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))
    

【讨论】:

以上是关于在 componentDidMount() 中获取地理位置并发送 Ajax 请求的主要内容,如果未能解决你的问题,请参考以下文章

axios在componentDidMount中获取数据后如何拍摄jest snapshot?

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

React componentDidMount() 初始化状态

如何让 componentDidMount 再次渲染?

Apollo + React:数据未出现在 componentDidMount 生命周期中

使用服务器端渲染获取数据的正确方法(Next.js,何时使用 componentDidMount 以及何时使用 componentWillMount)