无法在反应中使用this.setState设置状态

时间:2020-07-12 12:29:44

标签: javascript reactjs

我正在使用js的地理位置API来获取坐标。 已设置long和lat值。我通过console.log进行了检查,但是尽管调用了setState,但状态变量的经度和纬度仍未设置。

import React from 'react';

class Weather extends React.Component{
    constructor(props){
        super(props)
        this.state = {
            longitude : '',
            latitude : ''
        }
    }
    
    componentDidMount(){
        var long = 'a';
        var lat = 'b';
        var a = function(pos){
            long = pos.coords.longitude
            lat = pos.coords.latitude
        }
        
        navigator.geolocation.getCurrentPosition(a);
        this.setState({
            longitude: long,
            latitude: lat
        })
    }
    render(){
        return (
            <div className="container">
                <div className="city">
                    <h1>City Name</h1>
                        <h3>lon:{this.state.longitude}</h3>
                        <h3>{this.state.latitude}</h3>
                </div>
                <div className="icon">
                    
                </div>
            </div>
        )
    }
}
export default Weather

4 个答案:

答案 0 :(得分:0)

由于navigator.geolocation.getCurrentPosition是异步的,因此您可以使用async/await这样的功能:

声明获取当前位置的方法,await表示结果,然后设置状态。

getPosition = async () => {

  let promise = new Promise(function (resolve, reject) {
    navigator.geolocation.getCurrentPosition(resolve, reject);
  });

  let pos = await promise;

  this.setState({
    longitude: pos.coords.longitude,
    latitude: pos.coords.latitude
  })
}

然后在componentDidMount中调用此方法

componentDidMount(){
  this.getPosition();
}

答案 1 :(得分:0)

完成所有操作后,请尝试使componentDidMount()成为async函数。

import React from 'react';

class Weather extends React.Component{
    constructor(props){
        super(props)
        this.state = {
            longitude : '',
            latitude : ''
        }
    }
    
    async componentDidMount(){
        var long = 'a';
        var lat = 'b';
        var a = function(pos){
            long = pos.coords.longitude
            lat = pos.coords.latitude
        }
        
        await navigator.geolocation.getCurrentPosition(a);
        this.setState({
             longitude: long,
             latitude: lat
        })
    }
    render(){
        return (
            <div className="container">
                <div className="city">
                    <h1>City Name</h1>
                        <h3>lon:{this.state.longitude}</h3>
                        <h3>{this.state.latitude}</h3>
                </div>
                <div className="icon">
                    
                </div>
            </div>
        )
    }
}
export default Weather

答案 2 :(得分:0)

我只是通过@Apostolos答案中的一些修改来解决这个问题。

componentDidMount(){
        var long = 'a';
        var lat = 'b';
        
        async function getPosition(t) {
            let promise = new Promise(function (resolve, reject) {
              navigator.geolocation.getCurrentPosition(resolve, reject);
            });
            let pos = await promise;

            t.setState({
              longitude: pos.coords.longitude,
              latitude: pos.coords.latitude
            })
          }
          getPosition(this)
        
    }

答案 3 :(得分:0)

如果您不打算进一步将其getCurrentPosition转换为promise,则不必将其转换为promise。我认为最干净的解决方案是只在此处使用回调函数。

与您在问题中已执行的操作的重要区别在于,我将this.setState调用移到了getCurrentPosition回调中。

请注意,您必须使用arrow function来使this回调的getCurrentPosition值与componentDidMount函数内部的值相同。

componentDidMount() {
  navigator.geolocation.getCurrentPosition(
    ({coords: {longitude, latitude}}) => this.setState({longitude, latitude})
  );
}

有关{coords: {longitude, latitude}}语法的更多信息,我想将您重定向到MDN Destructing assignment - Object destructing页面。