componentWillMount中的异步调用在渲染方法后完成
问题描述:
我正在尝试对componentWillMount方法中的API执行异步调用。事实上,我希望render
方法在componentWillMount方法后执行,因为我需要将props
传递给我的render
方法中的组件。componentWillMount中的异步调用在渲染方法后完成
这里是我的代码:
class TennisSearchResultsContainer extends React.Component {
componentWillMount() {
// TODO: Build markers for the map
// TODO: Check courtsResults object and database for tennis court
this.courtsMarkers = this.props.courtsResults.map((court) => {
return new google.maps.Marker({
position: new google.maps.LatLng(JSON.parse(court.LOC).coordinates[1], JSON.parse(court.LOC).coordinates[0]),
title: court.NAME,
animation: google.maps.Animation.DROP
});
});
}
render() {
return <TennisSearchResults criterias={this.props.criterias} courtsMarkers={this.courtsMarkers} />;
}
}
我不那么明白,为什么我的渲染方法似乎不等待异步调用完成并通过不确定的道具,我的子组件...
我对不对?我应该怎么做才能解决这个问题?处理这个的方法是什么?
答
您可能需要更好地理解javascript异步行为。异步意味着“不要等待”。该任务将在后台执行,其他代码将继续执行。管理这个的好方法是在组件上设置状态。例如,当您输入componentWillMount
时,将loading
状态设置为true
。然后,当你的异步功能完成时,将该状态设置为false
。在您的render
功能中,您可以显示“加载...”消息或数据。
下面是一些代码,显示了获取数据异步的简化示例以及如何处理React中的数据。在浏览器中打开开发人员工具并查看控制台输出,以更好地理解React生命周期。
class MyComponent extends React.Component {
constructor(props) {
super();
console.log('This happens 1st.');
this.state = {
loading: false,
data: ''
};
}
loadData() {
// In real life you might use something like 'fetch' inside this
// function to get data.
// Since 'fetch' returns a promise, we can easily simulate that
// to keep the example simple.
var promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('This happens 5th (after 3 seconds).');
resolve('This is my data.');
}, 3000);
});
console.log('This happens 3rd.');
return promise;
}
componentWillMount() {
console.log('This happens 2nd.');
this.setState({ loading: true });
this.loadData()
.then((data) => {
console.log('This happens 6th.');
this.setState({
data: data,
loading: false
});
});
}
render() {
if (this.state.loading) {
console.log('This happens 4th - when waiting for data.');
return <h2>Loading...</h2>;
}
console.log('This happens 7th - after I get data.');
return (
<div>
<p>Got some data!</p>
<p>{this.state.data}</p>
</div>
);
}
}
ReactDOM.render(
<MyComponent />,
document.getElementsByClassName('root')[0]
);
您需要使用'componentDidMount'来代替'componentWillMount',只有在组件被安装到DOM之前运行一次。所以,不保证在AJAX调用之后组件将被渲染。 – Rowland
你的代码的哪部分是异步的?有很多谷歌地图调用,并不清楚它是否是其中之一,或其他。 –