2017-03-18 19 views
3

APIから気象データを取得する必要がある単純なアプリケーションを作成しています。終点。 私はReactに非常に新しいです。これはおそらくReactの約束事をどうやってどうやって作業するのか分かりません。ここReactJSアプリケーションの遅れて、プロミスの解決アクションが発生する

は私のコードである:

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(); 
    }); 
} 

私が約束を解決するために状態を設定しようとすると、私はいつも解決しません。

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" 
    }); 

私は間違っていますか?ありがとう!

答えて

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 
    }); 
}); 
+0

ありがとうございます!それが助けになった!私は今これをやっていて、さらに別の質問があります:http://stackoverflow.com/questions/42885936/unexpected-end-of-json-input-on-promise-resolveお手伝いしますか? – margarita

+0

@margarita 'React.createClass'は次のメジャーリリースで廃止予定です。彼らは別のパッケージに引き出す予定であるため、 '16.0.0'がリリースされた後も引き続き使用することができます。 ES6の 'class'を使って_stateful_コンポーネントをビルドすることができます。詳細については、以下 https://github.com/facebook/react/issues/8854 https://github.com/facebook/react/pull/9232 https://github.com/reactjs/ react-codemod#説明-new-es2015-class-transform-with-property-initializers – rockchalkwushock

+0

ありがとうございました!私は見てみましょう! – margarita

0

あなたは両方の成功とエラー条件の下で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)ex pects。たとえば、errorプロパティは不要です。

関連する問題