我正在尝试在componentWillMount方法中对API执行异步调用。实际上我希望在componentWillMount方法之后执行// Method returns first Item in ArrayQueue
template <class Item>
unsigned ArrayQueue<Item>::getFirst() const {
if (this->isEmpty()) {
throw EmptyQueueException("getFirst()");
} else {
return myArray[myFirst];
}
}
// Method returns last Item in ArrayQueue
template <class Item>
unsigned ArrayQueue<Item>::getLast() const {
if (this->isEmpty()) {
throw EmptyQueueException("getLast()");
} else {
return myArray[(myLast - 1 + myCapacity) % myCapacity];
}
}
方法,因为我需要将render
传递给props
方法中的组件。
这是我的代码:
render
我不明白为什么我的render方法似乎不等待异步调用完成并将未定义的道具传递给我的子组件......
我是对的吗?我该怎么做才能解决这个问题?处理这个问题的方法是什么?
答案 0 :(得分:56)
您可能需要更好地了解javascript异步行为。异步意味着不等待#34;任务将在后台执行,其他代码将继续执行。管理它的一个好方法是在组件上设置状态。例如,当您输入componentDidMount
时,将loading
州设置为true
。然后,当您的异步函数完成时,将该状态设置为false
。在render
功能中,您可以显示&#34; loading ...&#34;消息或数据。
以下是一些代码,它显示了获取数据异步的简化示例以及如何在React中处理它。在浏览器中打开开发人员工具,查看控制台输出,以更好地了解React生命周期。
编辑:自2018年4月起,代码已更新为使用新的React生命周期建议。总之,我将componentWillMount
替换为更安全的componentDidMount
。
在组件已经挂载之后更新状态似乎效率低下,因为&#39;组件 DID mount&#39;正确暗示。但是,根据official React documentation on componentDidMount:
&#34;如果您需要从远程端点加载数据,这是实例化网络请求的好地方。&#34;
&#34;在此方法中调用setState()
将触发额外呈现,但它将在浏览器更新屏幕之前发生。这保证即使在这种情况下将render()
被调用两次,用户也不会看到中间状态。&#34;
以下是完整的示例代码:
class MyComponent extends React.Component {
constructor(props) {
super();
console.log('This happens 1st.');
this.state = {
loading: 'initial',
data: ''
};
}
loadData() {
var promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('This happens 6th (after 3 seconds).');
resolve('This is my data.');
}, 3000);
});
console.log('This happens 4th.');
return promise;
}
componentDidMount() {
console.log('This happens 3rd.');
this.setState({ loading: 'true' });
this.loadData()
.then((data) => {
console.log('This happens 7th.');
this.setState({
data: data,
loading: 'false'
});
});
}
render() {
if (this.state.loading === 'initial') {
console.log('This happens 2nd - after the class is constructed. You will not see this element because React is still computing changes to the DOM.');
return <h2>Intializing...</h2>;
}
if (this.state.loading === 'true') {
console.log('This happens 5th - when waiting for data.');
return <h2>Loading...</h2>;
}
console.log('This happens 8th - after I get data.');
return (
<div>
<p>Got some data!</p>
<p>{this.state.data}</p>
</div>
);
}
}
ReactDOM.render(
<MyComponent />,
document.getElementsByClassName('root')[0]
);
最后,我认为React维护者Dan Abramov对现代React生命周期的这种形象有助于可视化发生的事情和时间。
请注意,从React 16.4开始,此生命周期图的误差很小:getDerivedStateFromProps
现在也在setState
以及forceUpdate
之后调用。请参阅官方React博客中有关Bugfix for getDerivedStateFromProps
此interactive version of the React lifecycle diagram允许您选择具有最新行为的React版本16.04。确保你检查&#34;显示不太常见的生命周期&#34;选项。
答案 1 :(得分:-2)
上面的答案可能对您尝试做的事情过于矫kill过正。您需要做的就是使compoentDidMount一个异步函数。然后,您可以在返回诺言的函数调用上使用await关键字。
class MyComponent extends React.Component {
async componentWillMount () {
await myAsyncCall();
}
render () {
}
}