状态未在地理定位函数中使用 setState 更新

State is not updating using setState in geolocation function

当我从地理位置 api 获取坐标时,我正在尝试更新状态。但是状态没有更新。我已将回调放在 setState 中以检查更新坐标的内容,但它是未定义的。 但是我不知道应该把这个setState放在哪里来更新实际坐标。


class App extends React.Component {
  constructor(props) {
    super(props);
    // App State
    this.state = {
      lat: 0,
      lng: 0
    };
  }
  // ComponentDIDMount
  componentDidMount() {
    // Get Data from json file

    $.getJSON("../resturants.json", data => {
      this.setState({
        resturantsList: data
      });
    });

    // Get location of user
    let success = position => {
      const latitude = position.coords.latitude;
      const longitude = position.coords.longitude;
      console.log(latitude, longitude);
      this.setState(
        {
          lat: latitude,
          lng: longitude
        },
        () => console.log(latitude, longitude)
      );
      console.log(this.state);
    };

    function error() {
      console.log("Unable to retrieve your location");
    }
    navigator.geolocation.getCurrentPosition(success, error);

    // Api call for resturants data
    const proxyurl = "https://cors-anywhere.herokuapp.com/";
    const url = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${this.state.lat},${this.state.lng}&radius=3000&type=restaurant&key=apikey`;
    console.log(url);
    fetch(proxyurl + url)
      .then(res => res.json())
      .then(
        result => {
          console.log(result.results);
          let apiResturants = result.results;
          let allResturants = this.state.resturantsList.concat(
            ...apiResturants
          );
          this.setState({
            resturantsList: allResturants
          });
        },

        error => {
          console.log("error");
        }
      );
  }
  }

  // Render function for app component
  render() {


  }
}

解决方法如下:

const getData = () => {
// Api call for resturants data
    const proxyurl = "https://cors-anywhere.herokuapp.com/";
    const url = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${this.state.lat},${this.state.lng}&radius=3000&type=restaurant&key=apikey`;
    console.log(url);
    fetch(proxyurl + url)
      .then(res => res.json())
      .then(
        result => {
          console.log(result.results);
          let apiResturants = result.results;
          let allResturants = this.state.resturantsList.concat(
            ...apiResturants
          );
          this.setState({
            resturantsList: allResturants
          });
        },

        error => {
          console.log("error");
        }
      );
  }
}


componentDidMount(){

  const success = position => {
  this.setState({lat: position.latitude, long: position.longitude}, () => {
  this.getData();
  })
  }
}

setState是异步操作,也就是说状态更新会在未来的时间完成。如果要检查状态何时更新,可以使用第二个参数。

this.setState({lat:latitude, long: longitude}, () => {console.log(this.state)});

第二个回调会告诉您确切的问题,因为它会在状态更新完成后调用。

因为你在一个粗箭头函数中,你可以使用 let self = this 重新定义你的 this,然后使用 self.setState 代替

不要进行异步调用,也不要在 React 组件的 constructor.

中调用 this.setState

You should not call setState() in the constructor().

使用componentDidMount生命周期函数获取数据和更新状态。

constructor(props) {
  super(props);

  // App State
  this.state = {
    lat: 0,
    lng: 0
  }
};

componentDidMount() {
  // Get location of user
  const success = position => {
    const latitude = position.coords.latitude;
    const longitude = position.coords.longitude;
    console.log(latitude, longitude);
    this.setState({
      lat: latitude,
      lng: longitude
    });
  };

  const error = () => {
    console.log("Unable to retrieve your location");
  };

  navigator.geolocation.getCurrentPosition(success, error);
}

状态更新是异步的

React 状态更新是异步的,并在当前渲染周期结束时排队等待处理。您正在访问来自 current 渲染周期的状态值,而不是下一个周期的状态值。将 navigator.geolocation.getCurrentPosition 调用中保存的纬度和经度值移动到 componentDidMount 的函数范围内,并在以后的 fetch 中使用它们,而不是使用状态 lat & lng.

componentDidMount() {
  // Get Data from json file

  $.getJSON("../resturants.json", data => {
    this.setState({
      resturantsList: data
    });
  });

  // Get location of user
  // Move latitude and longitude to function scope
  let latitude = 0;
  let longitude = 0;

  let success = position => {
    // cache values
    latitude = position.coords.latitude;
    longitude = position.coords.longitude;
    console.log(latitude, longitude);
    this.setState(
      {
        lat: latitude,
        lng: longitude
      },
      () => console.log(latitude, longitude)
    );
    console.log(this.state);
  };

  function error() {
    console.log("Unable to retrieve your location");
  }
  navigator.geolocation.getCurrentPosition(success, error);

  // Api call for resturants data
  const proxyurl = "https://cors-anywhere.herokuapp.com/";
  // use cached lat & long values
  const url = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${
    latitude
  },${longitude}&radius=3000&type=restaurant&key=apikey`;
  console.log(url);
  fetch(proxyurl + url)
    .then(res => res.json())
    .then(
      result => {
        console.log(result.results);
        let apiResturants = result.results;
        let allResturants = this.state.resturantsList.concat(
          ...apiResturants
        );
        this.setState({
          resturantsList: allResturants
        });
      },

      error => {
        console.log("error");
      }
    );
}