【问题标题】:Promise resolve action is triggered late in ReactJS app承诺解决动作在 ReactJS 应用程序后期触发
【发布时间】:2017-08-10 07:49:27
【问题描述】:

我正在编写一个简单的应用程序,它需要从 API 获取一些天气数据。端点。 我对 React 很陌生,所以这可能是我不了解如何在 React 中使用 Promise。

这是我的代码:

var React = require('react');

var Weather = React.createClass({
   getInitialState: function() {
     console.log('GetInitialState', 'info');
      return {
        foo : 1,
        weatherConditions : "No weather data"
      };  
   },

   update: function() {
     console.log('Updating State', 'primary');
     let self = this;
     function httpRequestWeather(url) {
       return new Promise(function(resolve, reject) {
          var weatherRequest = new XMLHttpRequest();
          weatherRequest.open("GET", url, true);
          weatherRequest.onreadystatechange = function() {
            if ( this.status === 200) {
                console.log("request finished and response is ready");
                console.log(this.response);
                // only returns when I post code here
                self.setState({
                    weatherConditions: this.response
                 });

                resolve(this.response);
            } else{
                reject(new Error("no weather data"));
            }
          };
        weatherRequest.send();
      });
     }
  httpRequestWeather("www.weatherendpoint.con/json").then(function(responseText){
    let text = JSON.parse(responseText);
    //never gets triggered
    self.setState({
        weatherConditions: "Hi"
     });
  }).catch(function(){
     //always triggered
    self.setState({
        weatherConditions: "Buy"
     });
});

  this.setState({foo: 2});
},

 render: function() {
   console.log('Render', 'success');
   let condition = this.state.weatherConditions;
   return (
    <div>
        <span>{condition} </span>
        <span>{this.state.foo} </span>
    </div>
    )
  },

 componentWillMount: function() {
  console.log('ComponentWillMount', 'warning');
  this.update();
 },

 componentDidMount: function() {
   console.log('ComponentDidMount', 'warning');
   this.update();

 },

shouldComponentUpdate: function() {
  console.log('ShouldComponentUpdate', 'info');
  return true;
}

 });

module.exports = Weather;

基本上,问题是在这个函数中我必须触发 self.setState({weatherConditions: this.response});

function httpRequestWeather(url) {
   return new Promise(function(resolve, reject) {
      var weatherRequest = new XMLHttpRequest();
      weatherRequest.open("GET", url, true);
      weatherRequest.onreadystatechange = function() {
        if ( this.status === 200) {
            console.log("request finished and response is ready");
            console.log(this.response);
            // only returns when I post code here
            self.setState({
                weatherConditions: this.response
             });

            resolve(this.response);
        } else{
            reject(new Error("no weather data"));
        }
      };
    weatherRequest.send();
  });
 }

如果我尝试在 promise resolve 上设置状态,我总是无法解决。

httpRequestWeather("www.weatherendpoint.con/json").then(function(responseText){
let text = JSON.parse(responseText);
    //never gets triggered
    self.setState({
       weatherConditions: "Hi"
    });
  }).catch(function(){
    //always triggered
    self.setState({
      weatherConditions: "Buy"
    });

我做错了什么?谢谢!

【问题讨论】:

    标签: javascript ajax reactjs promise es6-promise


    【解决方案1】:

    您在执行请求时遇到错误。您应该首先检查错误,看看为什么会得到它,并根据该错误为错误流设置适当的state

    httpRequestWeather("www.weatherendpoint.con/json")
     .then(function(responseText){
        let text = JSON.parse(responseText);
        self.setState({
           weatherConditions: "Hi"
        });
      }).catch(function(err){
        console.log('Error on request:', err);
        self.setState({
          error: err
        });
     });
    

    【讨论】:

    【解决方案2】:

    如果您想在成功和错误两种情况下都调用self.setState(...),那么以下模式可能很有用:

    asyncRequest()
    .then(function(data) {
        return { /* properties */ }; // state object (success)
    }, function(err) {
        console.log(err);
        return { /* properties */ }; // state object (something suitable to describe an error)
    })
    .then(self.setState);
    

    所以你可以在这里写:

    httpRequestWeather() // pass url if necessary
    .then(function(weatherData) { // make sure `httpRequestWeather()` delivers data, not a JSON string.
        return {
            'weatherConditions': weatherData,
            'error': null
        };
    }, function(err) {
        console.log('Error on request:', err); // optional
        return {
            'weatherConditions': 'unknown',
            'error': err
        }
    })
    .then(self.setState);
    

    上面的特定属性只是我对可能有用的想法,并且可以根据self.setState(和/或self.render)的期望进行调整。例如,error 属性可能是不必要的。

    【讨论】:

      猜你喜欢
      • 2017-02-18
      • 1970-01-01
      • 1970-01-01
      • 2016-12-03
      • 2016-04-05
      • 1970-01-01
      • 2016-01-10
      • 2020-01-18
      • 2015-06-24
      相关资源
      最近更新 更多