我正在使用打字稿/反应,对异步功能的理解是很基本的。
我必须进行两个API调用,并且具有从异步UI调用它们的函数。我绝对需要完成这些调用才能正确呈现组件,但是感觉到整个组件的功能必须声明为异步才能发生。
我在getOverview()
中通过添加等待来解决了一个问题,但是现在,我的问题是createPage()
函数不等待getOverview()
返回的列表中包含项目以便对其执行任何操作,因此最终会出错。我还需要等待此功能吗?
等待的人不断攀升,我不知道它是否正确。
class overview extends React.Component<any, any> {
constructor(props) {
super(props);
this.state = {
overviewList: [],
};
}
async callAPI1() {
return await api1()
.then((result) => {
if (result.status_code === 200) {
// return result data
} else {
// error redirect
}
});
}
async callAPI2() {
return await api2()
.then((result) => {
if (result.status_code === 200) {
// return result data
} else {
// error redirect
}
});
}
async getOverview() {
const list = [];
list.concat(await this.callAPI1());
list.concat(await this.callAPI2());
this.setState({overviewList: list});
return list;
}
createPage() {
const overview = this.getOverview();
return overview[1];
}
render() {
return (
<div>
<h1>Header</h1>
{ this.createPage() }
</div>
);
}
}
答案 0 :(得分:1)
我怀疑您想为React内部发生的每个渲染调用外部API。因此,您通常不会在render
函数内部调用调用API调用的方法。它们主要在componentDidMount
和/或componentDidUpdate
内部使用。
以下是基于您的代码的示例:
class overview extends React.Component<any, any> {
constructor(props) {
super(props);
this.state = {
overviewList: [],
};
}
async callAPI1() {
return this.trowIfNot200(await api1());
}
async callAPI2() {
return this.trowIfNot200(await api2());
}
throwIfNot200(result) {
if (result.status_code === 200) {
return result;
} else {
throw result;
}
}
async componentDidMount() {
try {
const overviewList = await Promise.all([this.callAPI1(), this.callAPI2()]);
this.setState({overviewList});
} catch (error) {
this.setState({error: "There was a problem loading external data."}));
}
}
render() {
if (this.state.error) {
return <div>{this.state.error}</div>;
} else {
return (
<div>
<h1>Header</h1>
{ this.state.overviewList[1] }
</div>
);
}
}
}
请注意,只要数据仍在加载,this.state.overviewList[1]
将返回undefined
。对于undefined
,null
或false
的值,React不会呈现任何内容。
ReactDOM.render(
<div>a {undefined} b {null} c {false} d</div>,
document.querySelector("#root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>