2017-03-18 1 views
3

Ich schreibe eine einfache App, die einige Wetterdaten von einer API erhalten muss. Endpunkt. Ich bin sehr neu in React, deshalb verstehe ich wahrscheinlich nicht, wie ich mit Reactions arbeiten soll.Promise Auflösungsaktion wird spät in ReactJS App ausgelöst

Hier ist mein Code:

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; 

Grundsätzlich ist das Problem, dass ich in dieser Funktion self.setState auslösen haben ({Wetterbedingungen: this.response});

Wenn ich versuche, Zustand auf Versprechen zu lösen, werde ich immer ungelöst.

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

Was mache ich falsch? Vielen Dank!

Antwort

1

Sie erhalten einen Fehler während der Anfrage. Sie sollten zuerst den Fehler überprüfen, dann sehen Sie, warum Sie ihn bekommen, und basierend darauf den state entsprechend für den Fehlerfluss setzen.

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

Vielen Dank! Das hat geholfen! Ich mache das gerade jetzt und habe noch eine Frage: http://stackoverflow.com/questions/42885936/unexpected-end-of-json-input-on-promise-resolve. Macht es Ihnen etwas aus? – margarita

+0

@margarita nur ein FYI, dass 'React.createClass' in der nächsten Hauptversion veraltet ist. Sie planen, es zu einem separaten Paket herauszuziehen, damit es nach der Veröffentlichung von "16.0.0" noch verwendet werden kann. Sie können ES6 'class' verwenden, um _stateful_-Komponenten zu erstellen. Für weitere Informationen: https://github.com/facebook/react/issues/8854 https://github.com/facebook/react/pull/9232 https://github.com/reactjs/ react-codemod # erklärung-des-neuen-es2015-class-transform-with-property-initializers – rockchalkwushock

+0

Vielen Dank! Ich werde mal schauen! – margarita

0

Wenn Sie self.setState(...) unter beiden Erfolgs- und Fehlerbedingungen nennen wollen, dann könnte das folgende Muster nützlich sein:

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

Also hier können Sie schreiben:

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

Die besondere Eigenschaften oben sind nur meine Idee von dem, was nützlich sein könnte, und sind offen für die Anpassung nach was self.setState (und/oder self.render) ex pekte. Zum Beispiel kann die Eigenschaft error unnötig sein.

Verwandte Themen