use*_*641 1 javascript fetch reactjs react-native react-native-android
我试图用fetch()我的React Native Component中的函数处理错误的HTTP响应.我使用了这里的代码,建议创建一个模块来处理响应错误.
// 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 };
Run Code Online (Sandbox Code Playgroud)
这是我的组件的代码:
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
Run Code Online (Sandbox Code Playgroud)
我已确保测试服务器当前正在提供502 Gateway错误.
我期望的行为是,当行抛出错误时,.then(ApiUtils.checkStatus)它应该被.catch函数捕获并且状态应该被更新this.setState({load_failed: true});.但是,我收到错误消息ExceptionsManager.js:55 this.setState is not a function.
我觉得这很奇怪,因为下面的.then( . . .)函数在它上面的函数中起作用:
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData),
loaded: true,
});
Run Code Online (Sandbox Code Playgroud)
为什么.catchlambda无法访问上this.setState一个函数的位置?我可以用.bind()某种方式吗?
如果无法this.setState在catch函数内访问,如果我的HTTP响应不佳,如何更改state.load_failed为true?
我试图将异常传递给调用函数,然后从父函数更改状态,如下所示:
我将.catch()功能更改为:
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();
}
Run Code Online (Sandbox Code Playgroud)
然后改变调用函数,如下所示:
componentDidMount(){
try{
this.fetchData();
}
catch(error){
this.setState({load_failed: true});
}
console.log(this.state.load_failed);
Run Code Online (Sandbox Code Playgroud)
}
但是,我得到一个简单的ExceptionsManager.js:55 Error.
我尝试删除.done(),但是catch块无法处理异常,状态没有改变,我收到警告:Possible Unhandled Promise Rejection (id: 0):.我意识到这可能与javascript中的异步函数以及传递给错误的内容有关,但我并不是100%肯定.
环境:OSX 10.10,Android 4.1.2,React-native 0.29.2
您的函数未按this预期在相同的上下文(值)中运行.要解决这个问题,请使用保持相同的箭头功能this:
.catch(error => {
console.log("Error:" + error.message);
this.setState({load_failed: true});
})
Run Code Online (Sandbox Code Playgroud)
或明确bind地对当前this:
.catch(function(error){
console.log("Error:" + error.message);
this.setState({load_failed: true});
}.bind(this))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6652 次 |
| 最近记录: |