Reagieren-native fetch fehlschlägt, um setState wenn der Fehler geworfen wird
Hintergrund
Ich versuche zu handhaben, ein bad HTTP-Antwort mit der fetch()
Funktion in meine Reagieren Nativen Komponente. Ich habe den code von hier, die empfiehlt die Schaffung einer Modul-handle-response-Fehler.
//ApiUtils.js
var ApiUtils = {
checkStatus: function(response) {
if (response.status >= 200 && response.status < 300) {
return response;
} else {
let error = new Error(response.statusText);
error.response = response;
throw error;
}
}
};
export { ApiUtils as default };
Dies ist der code für meine Komponente:
import React, { Component } from 'react';
import {View, Text, StyleSheet, Slider, ListView} from 'react-native';
import GLOBAL from "../../Globals.js"
import ApiUtils from "../utils/ApiUtils.js"
class FetchedList extends Component {
constructor(props) {
super(props);
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 != row2,
}),
loaded: false,
load_failed: false,
};
}
componentDidMount(){
this.fetchData();
}
fetchData(){
fetch(GLOBAL.BASE_URL + "/" + this.props.url_section + "/" + String(this.props.weekNo) + "/")
.then(ApiUtils.checkStatus)
.then((response) => {
return response.json()
})
.then((responseData) => {
if(responseData===[] || responseData.length === 0){
this.setState({
loaded: false,
load_failed: true,
});
}
else{
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData),
loaded: true,
});
}
})
.catch(function(error){
console.log("Error:" + error.message);
this.setState({load_failed: true});
})
.done();
}
render() {
if (!this.state.loaded) {
if (this.state.load_failed){
return(
<View></View>
);
}
return this.renderLoadingView();
}
else{
return (
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderComment}
/***//>
);
}
}
renderLoadingView() {
return (
<View>
<Text>Loading . . .</Text>
</View>
);
}
renderComment(comment){
return(
<Text style={styles.row}>{comment.content}</Text>
)
}
}
const styles = StyleSheet.create({
row: {
//backgroundColor: "antiquewhite",
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center",
height: 50
},
});
module.exports = FetchedList
Habe ich darauf geachtet, dass die test-server ist derzeit mit 502 Gateway Fehler.
Verhalten ich erwarten, ist, dass wenn ein Fehler ausgelöst wird durch die Linie .then(ApiUtils.checkStatus)
sollte es sein gefangen durch die .catch
Funktion und Status aktualisiert werden sollte, indem this.setState({load_failed: true});
. Allerdings bekomme ich die Fehlermeldung ExceptionsManager.js:55 this.setState is not a function
.
Ich finde das seltsam, denn die folgenden arbeiten innerhalb der .then( . . .)
Funktion oben:
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData),
loaded: true,
});
Frage
Warum die .catch
lambda nicht haben Zugang zu this.setState
wo die Vorherige Funktion verrichtet? Kann ich .bind()
irgendwie?
Folgen-Auf Die Frage
Wenn es nicht möglich ist, Zugriff auf this.setState
innerhalb der catch
Funktion, wie kann ich das ändern state.load_failed
zu true
wenn ich eine schlechte HTTP-Antwort?
Versuchte Behebt
Habe ich versucht, übergeben Sie die Ausnahme an die aufrufende Funktion, und ändern Sie dann den Status aus der übergeordneten Funktion, etwa so:
Änderte ich die .catch()
Funktion zu diesem:
fetchData(){
fetch(GLOBAL.BASE_URL + "/" + this.props.url_section + "/" + String(this.props.weekNo) + "/")
.then(ApiUtils.checkStatus)
.then((response) => {
return response.json()
})
.then((responseData) => {
. . .
})
.catch(function(error){
console.log("Error!");
throw error;
})
.done();
}
und dann verändert die aufrufende Funktion so auf:
componentDidMount(){
try{
this.fetchData();
}
catch(error){
this.setState({load_failed: true});
}
console.log(this.state.load_failed);
}
Aber ich bekomme dann eine einfache ExceptionsManager.js:55 Error
.
Ich habe versucht, das entfernen .done()
, aber die catch
block schlägt fehl, zum behandeln der Ausnahme, Status ändert sich nicht und ich bekomme eine Warnung: Possible Unhandled Promise Rejection (id: 0):
. Mir ist klar, dass das möglicherweise etwas zu tun mit dem async-Funktionen in javascript und was der Fehler ist weitergegeben, aber ich bin mir nicht 100% sicher.
Umgebung: OSX 10.10, Android 4.1.2, Reagieren-native 0.29.2
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre Funktion wird nicht ausgeführt in den gleichen Kontext (
this
- Wert) wie erwartet. Um dieses Problem zu lösen, verwenden Sie entweder einen Pfeil Funktion bleibt die gleichethis
:oder explizit
bind
zu den aktuellenthis
: