【发布时间】:2017-12-31 21:58:35
【问题描述】:
简化问题。在 Promise 中调用 this.setState,在未决 Promise 结束之前渲染。
我的问题是:
- this.setState 不会立即返回
- 我希望它是异步的,因此待处理的 Promise 将首先关闭。
- 如果渲染函数内部出现问题,则调用 Promise 中的 catch。
- 可能与 1) 相同的问题是,渲染似乎仍在调用 this.setState 的承诺的上下文中。
import dummydata_rankrequests from "../dummydata/rankrequests";
class RankRequestList extends Component {
constructor(props) {
super(props);
this.state = { loading: false, data: [], error: null };
this.makeRankRequestCall = this.makeRankRequestCall.bind(this);
this.renderItem = this.renderItem.bind(this);
}
componentDidMount() {
// WORKS AS EXPECTED
// console.log('START set');
// this.setState({ data: dummydata_rankrequests.data, loading: false });
// console.log('END set');
this.makeRankRequestCall()
.then(done => {
// NEVER HERE
console.log("done");
});
}
makeRankRequestCall() {
console.log('call makeRankRequestCall');
try {
return new Promise((resolve, reject) => {
resolve(dummydata_rankrequests);
})
.then(rankrequests => {
console.log('START makeRankRequestCall-rankrequests', rankrequests);
this.setState({ data: rankrequests.data, loading: false });
console.log('END _makeRankRequestCall-rankrequests');
return null;
})
.catch(error => {
console.log('_makeRankRequestCall-promisecatch', error);
this.setState({ error: RRError.getRRError(error), loading: false });
});
} catch (error) {
console.log('_makeRankRequestCall-catch', error);
this.setState({ error: RRError.getRRError(error), loading: false });
}
}
renderItem(data) {
const height = 200;
// Force a Unknown named module error here
return (
<View style={[styles.item, {height: height}]}>
</View>
);
}
render() {
let data = [];
if (this.state.data && this.state.data.length > 0) {
data = this.state.data.map(rr => {
return Object.assign({}, rr);
});
}
console.log('render-data', data);
return (
<View style={styles.container}>
<FlatList style={styles.listContainer1}
data={data}
renderItem={this.renderItem}
/>
</View>
);
}
}
当前日志显示:
- 渲染数据,[]
- 开始 makeRankRequestCall-rankrequests
- 渲染数据,[...]
- _makeRankRequestCall-promisecatch 错误:未知的命名模块...
- 渲染数据,[...]
- 可能未处理的承诺
安卓模拟器 “反应”:“16.0.0-alpha.12”, "react-native": "0.46.4",
编辑: 围绕 this.setState 包裹 setTimeout 也可以
setTimeout(() => {
this.setState({ data: respData.data, loading: false });
}, 1000);
EDIT2: 在 react-native github 中并行创建了一个错误报告 https://github.com/facebook/react-native/issues/15214
【问题讨论】:
-
我无法准确确定您要解决的问题。您是否尝试在执行
console.log("done");时只重新渲染一次?如果是这样,实现它的一种方法是覆盖shouldComponentUpdate(),因此当您准备好重新渲染时,它总是返回false和this.forceUpdate。 facebook.github.io/react/docs/react-component.html#forceupdate
标签: react-native