2017-04-09 181 views
14

我正在尝试对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} />; 
    } 
} 

我不那么明白,为什么我的渲染方法似乎不等待异步调用完成并通过不确定的道具,我的子组件...

我对不对?我应该怎么做才能解决这个问题?处理这个的方法是什么?

+2

您需要使用'componentDidMount'来代替'componentWillMount',只有在组件被安装到DOM之前运行一次。所以,不保证在AJAX调用之后组件将被渲染。 – Rowland

+0

你的代码的哪部分是异步的?有很多谷歌地图调用,并不清楚它是否是其中之一,或其他。 –

回答

24

您可能需要更好地理解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] 
); 

这里是working example on CodePen

相关问题