Here’s what I do normally:
class Login extends React.Component {
constructor(props) {
//IMPLEMENT OTHER JUNK HERE
this.state = {
data: null //This is what our data will eventually be loaded into
};
}
componentDidMount() {
this.loadData();
}
loadData() {
/*LOAD DATA, INSERT BELOW LINE IN CALLBACK FUNCTION
this.setState({
data: //LOADED DATA
});
*/
}
render() {
if (!this.state.data) {
return <div />
}
//WE HAVE DATA, DO A NORMAL RENDER
return (
<div id="login-page">
<div className="container-fluid">
<div className="row">
<div className="col-md-2">
<Link to="https://stackoverflow.com/" className="home-link"><img src={BASE_URL + '/assets/img/logo.svg'} alt="Logo" /></Link>
</div>
</div>
<div className="row">
<div className="col-lg-4 col-lg-offset-4">
<h1><FormattedMessage {...messages.loginPageTitle} /></h1>
</div>
</div>
{React.cloneElement(this.props.children || <div />, { onSubmit: this.handleFormSubmit, login: this.props.login })}
</div>
</div>
);
}
}
Here’s a breakdown of what is going to happen…
- Component is going to load
- componentDidMount() fires, runs loadData()
- loadData() starts ajax request, returns before ajax request returns data because we love asynchronous data loads
- render() runs. Since
this.state.data
isnull
, we have pass into the if block, and<div />
is returned. - Ajax data load finishes, and a
this.setState()
call is made, which forces a re-render. - render() runs again. Since
this.state.data
contains a value now, we skip over the if block and render our normal stuff.
Edit (11 Oct 2019): Migrated componentWillMount() to componentDidMount()