2017-04-09 13 views
14

componentWillMountメソッドでAPIへの非同期呼び出しを実行しようとしています。実際にrenderメソッドのコンポーネントにpropsを渡す必要があるので、renderメソッドをcomponentWillMountメソッドの後に実行したいと思います。ここで レンダリングメソッドの後に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

代わりに 'componentDillMount'を使う必要があります。なぜなら、' componentWillMount'はコンポーネントがDOMにマウントされる前に一度だけ実行されるからです。したがって、AJAX呼び出しの後にコンポーネントがレンダリングされるという保証はありません。 – Rowland

+0

コードのどの部分が非同期ですか?多くのGoogleマップの通話があり、そのいずれかであるかどうかは不明です。 –

答えて

24

javascriptの非同期動作をよりよく理解する必要がある場合があります。非同期は「待たないでください」を意味します。タスクはバックグラウンドで実行され、他のコードは引き続き実行されます。これを管理する良い方法は、コンポーネントに状態を設定することです。たとえば、componentWillMountと入力すると、trueloadingの状態が設定されます。その後、非同期関数が完了したら、その状態をfalseに設定します。 render関数では、「読み込み中...」というメッセージまたはデータを表示することができます。

ここでは、非同期データを取得する簡単な例と、それを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があります。

関連する問題