当抛出错误时,反应本机提取无法设置状态
React-native fetch failing to setState when error is thrown
Background
我正在尝试使用我的 React Native 组件中的 fetch()
函数处理错误的 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 };
这是我的组件的代码:
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
我已确保测试服务器当前给出 502 网关错误。
我期望的行为是,当行抛出错误时,.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,
});
问题
为什么 .catch
lambda 无法访问前一个函数可以访问this.setState
?我可以以某种方式使用.bind()
吗?
后续问题
如果无法访问catch
函数中的this.setState
,那么如果我得到糟糕的 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();
}
然后像这样更改调用函数:
componentDidMount(){
try{
this.fetchData();
}
catch(error){
this.setState({load_failed: true});
}
console.log(this.state.load_failed);
}
但是,我随后得到了一个简单的ExceptionsManager.js:55 Error
.
我尝试删除.done()
,但catch
块无法处理异常,状态没有改变,我收到警告:Possible Unhandled Promise Rejection (id: 0):
。我意识到这可能与 javascript 中的异步函数以及错误传递给什么有关,但我不是 100% 确定。
环境:OSX 10.10,安卓 4.1.2,反应原生 0.29.2
您的函数未在与预期相同的上下文(this
值(中运行。要解决此问题,请使用保持相同this
的箭头函数:
.catch(error => {
console.log("Error:" + error.message);
this.setState({load_failed: true});
})
或明确bind
当前this
:
.catch(function(error){
console.log("Error:" + error.message);
this.setState({load_failed: true});
}.bind(this))
- '图片'没有用于本机道具的propType'RCTImageView.overlayColor&
- 在iOS和Android上使用React native时,我还能使用本机第三方lirbraries吗
- javascript函数访问ios本机功能
- 如何在从客户端接收数据时从本机方法触发javascript函数?
- 在浏览器中检测本机或第三方PDF插件
- 将事件发送到javascript文档的react本机模块是否正确
- 将对应用内购买的支持构建为react本机代码
- 如何在Windows上用javascript构建本机应用程序
- 在视图中渲染多个按钮以编程方式进行本机反应
- 在本机挂钩之前加载可安装挂钩
- 如何使用UI Automation JavaScript Reference for iOS appium获取本机应用程
- 控制台中的“function floor(){[本机代码]}”是什么
- 如何将chrome.tabCapture流从js传递到c++PNACL本机代码
- WKWebview-Javascript和;本机代码
- 将回调/函数从本机发送到javascript
- 为什么我得到Chrome本机消息“;找不到指定的本机消息传递主机&”;
- 检测未绑定的本机函数,如“Array.push”
- 离子 - 本机对话框
- 如何获取 jQuery 以触发本机自定义事件处理程序
- 当抛出错误时,反应本机提取无法设置状态