setState即使在回调后也不会更新。在循环中调用this.state.loop不会呈现更新的状态

时间:2020-07-05 05:08:27

标签: reactjs callback react-redux state setstate

在这里,我正在使用await和一个回调将state设置为store_result状态,并将其设为await调用。这样,当我调用该函数时,它就已经更新了。我读了许多相关的文章并添加了回调,但是我似乎无法理解为什么它不起作用。

await this.setState({ store_result: this.state.store_result}, function () {
      console.log(this.state.store_result);
    });


    this.CalculateDetails();

当我使用setState进行console.log(store_results)时,状态会更新,但是handleDetails仍然会收到一个空的store_result。

handleSelect = async address => {
    let results = await  geocodeByAddress(address)
    let latLng = await getLatLng(results[0]);
    this.state.coordsPair.push(latLng);

    let codeResults = await geocodeByAddress(address)

    console.log(this.state.coordsPair)
    const {coordsPair} = this.state;
    const {store_result}= this.state;

    let map = new google.maps.Map(document.createElement('div'));
    this.googlePlaces = new google.maps.places.PlacesService(map);

    var request = {
      location: coordsPair[0],
      radius: '5000',
      type: ['restaurant','point_of_interest']
    };

    
    this.googlePlaces.nearbySearch(request, callback);

    function callback(results, status) {
      if (status == google.maps.places.PlacesServiceStatus.OK) {
        console.log(results.length);
        for (var i = 0; i < results.length; i++) {
          store_result.push(results[i].place_id)
        }
      }
    }

    await this.setState({ store_result: this.state.store_result}, function () {
      console.log(this.state.store_result);
    });


    this.CalculateDetails();

  };

这是在回调设置状态之后调用的函数。

CalculateDetails(){
 
  console.log("details");

    const {store_result}= this.state; 
    const {details} = this.state;
    var wait;
    for(var i = 0; i < store_result.length; i++) {
      //console.log("4");
      let map = new google.maps.Map(document.createElement('div'));
      this.googlePlaces = new google.maps.places.PlacesService(map);

      var request2 = {
        placeId: store_result[i],
        fields: ['name', 'rating', 'formatted_phone_number', 'geometry','website','opening_hours','review','price_level']
      };
      //console.log("1");
  
      this.googlePlaces.getDetails(request2, callback2);

      function callback2(place, status) {
        if (status == google.maps.places.PlacesServiceStatus.OK) {
          details.push(place);
  
        }
    }
   
  }

 this.setState({ details: this.state.details}, function () {
      console.log(this.details);
    });
}

当前更新 我已经将handleSelect函数更新为

 handleSelect = async (address) => {
    let results = await geocodeByAddress(address);
    let latLng = await getLatLng(results[0]);
    this.state.coordsPair.push(latLng);
  
    let codeResults = await geocodeByAddress(address);
  
    console.log(this.state.coordsPair);
    const { coordsPair } = this.state;
    const { store_result } = this.state;
    const store_result_updated = [...store_result]; //<----here
  
    let map = new google.maps.Map(document.createElement("div"));
    this.googlePlaces = new google.maps.places.PlacesService(map);
  
    var request = {
      location: coordsPair[0],
      radius: "5000",
      type: ["restaurant", "point_of_interest"],
    };
  
    this.googlePlaces.nearbySearch(request, callback);
  
    function callback(results, status) {
      if (status == google.maps.places.PlacesServiceStatus.OK) {
        console.log(results.length);
        for (var i = 0; i < results.length; i++) {
          store_result_updated.push(results[i].place_id);//<----here
        }
      }
    }
  
    this.setState({ store_result: store_result_updated }, function () {
      //<----here
      console.log(this.state.store_result);
      this.calculateDetails();

    });
  
  };

这是calculateDetails()的当前更新。奇怪的是,check1将一个长度打印为0,而check2甚至没有打印出for循环内的长度。

calculateDetails(){
 
  console.log("details");

    const {store_result}= this.state; 
    const {details} = this.state;
  
    const details_updated = [...details]; //<----here

    let map = new google.maps.Map(document.createElement('div'));
    this.googlePlaces = new google.maps.places.PlacesService(map);
    console.log(store_result.length);//-> check1

    for(var i = 0; i < store_result.length; i++) {
      console.log(this.state.store_result.length); //check2
      

      var request2 = {
        placeId: store_result[i],
        fields: ['name', 'rating', 'formatted_phone_number', 'geometry','website','opening_hours','review','price_level']
      };
      
      this.googlePlaces.getDetails(request2, callback2);

      function callback2(place, status) {
        if (status === google.maps.places.PlacesServiceStatus.OK) {
          details_updated.push(place);
  
        }

        
    }

    this.setState({ details: details_updated}, function () {
      console.log(this.state.details);
   });
   
  }

}

2 个答案:

答案 0 :(得分:0)

您不能await setState,因为它不是异步功能。设置状态后,将调用作为setState的第二个参数的回调。在此处致电CalculateDetails(应命名为calculateDetails)。

答案 1 :(得分:0)

您正在直接更改状态(在for循环中),这不会导致任何重新渲染。

此外,this.setState({ store_result: this.state.store_result}将从错误状态中存储相同的值。

此外,完全不需要setState。

重构代码

handleSelect = async (address) => {
  let results = await geocodeByAddress(address);
  let latLng = await getLatLng(results[0]);
  this.state.coordsPair.push(latLng);

  let codeResults = await geocodeByAddress(address);

  console.log(this.state.coordsPair);
  const { coordsPair } = this.state;
  const { store_result } = this.state;
  const store_result_updated = [...store_result]; //<----here

  let map = new google.maps.Map(document.createElement("div"));
  this.googlePlaces = new google.maps.places.PlacesService(map);

  var request = {
    location: coordsPair[0],
    radius: "5000",
    type: ["restaurant", "point_of_interest"],
  };

  this.googlePlaces.nearbySearch(request, callback);

  function callback(results, status) {
    if (status == google.maps.places.PlacesServiceStatus.OK) {
      console.log(results.length);
      for (var i = 0; i < results.length; i++) {
        store_result_updated.push(results[i].place_id);//<----here
      }
    }
  }

  this.setState({ store_result: store_result_updated }, function () {
    //<----here
    console.log(this.state.store_result);
  });

  this.CalculateDetails();
};