Load data from backend before rendering a React component – best practice

Where to put the data fetching code?

componentWillMount() ? Not any more. It’s been deprecated.

You have no choice but put it inside componentDidMount() , which is recomendded by React.

However ther is a big issue. componentDidMount() is actually AFTER render(). It "works" because after componentDidMount() finishes its job and changes some state, render() will be called again. So render() will be called twice. The first time of rendering may break

The solution

  • Put the logic inside componentDidMount()
  • Inside render() method, check if the data is ready. If yes, render the component; otherwise, render null
  • When data is loading, show a spin or a loading bar. This way the user won’t be confused by empty content
  • Clean the state inside componentWillUnmount(). If you don’t do this, the data is alwasy "ready" at the step above, so no empty content will be shown
  • Better use a connector component to do all this dirty work

Code Sample

//1,2,3,4,5,6 in the comment is the order that the statements are executed 

class UserProfileComponentContainer extends React.Component { // the container component 
    componentDidMount() {
        this.props.dispatch(getMyProfileAsyncAction(this.props.rootState.token));   //2
    }

    componentWillUnmount(){
        this.props.dispatch(cleanProfileLocallyAction());  //5  (when the user leaves the component) 
    }

    render() {
        if (hasUserProfile(this.props.rootState)) { //data is ready 
            return <UserProfileComponent userProfile={this.props.rootState.userProfile}/>   //4 
        } else {
            return null;  //1, 3, 6 (when the user come back to this component) 
        }
    }
}

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.