Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load the component when all data has ready

I'm using React with Redux. In this example I have my class with mapStateToProps and mapDispatchToProps

class EnigmaPage extends Component {

    constructor(props){
        super(props);
    }

    componentDidMount() {
        this.props.authCheckState();
    }

    readUserData() {
        this.props.loadLevel(this.props.userId);
    }

    render(){
        return (
            <div className={classes.EnigmaPage}>
                <div className={classes.Header}>
                    <div>
                        <LevelInfo 
                            difficulty={this.props.level.difficulty}
                            level={this.props.level.level}
                            readUserData={this.readUserData()}
                        />

                    </div>
                </div>
            </div>
        )
    }

}

const mapDispatchToProps = dispatch => {
    return {
        authCheckState: () => dispatch(actions.authCheckState()),
        getLevel: () => dispatch(actions.getLevel()),
        loadLevel:(id) => dispatch(actions.loadLevel(id))
    };
}
const mapStateToProps = state => {
    return {
        userId:state.auth.user,
        level:state.level.level
    }
}

I wanna push to my component LevelInfo the values difficulty and level but these 2 data arrive from getLevel() that is an http request with delay.
The page loads before receiving all the data from the http call.
I'm looking a way to wait to load the component LevelInfo or reload the component when the data are all ready.

like image 401
Marco Pestrin Avatar asked Dec 18 '18 23:12

Marco Pestrin


2 Answers

We don't make our components wait, we let the initial rendering happens but render the target component with a conditional expression.

render() {
  return (
    <div className={classes.EnigmaPage}>
      <div className={classes.Header}>
        <div>
          {this.props.level && (
            <LevelInfo
              difficulty={this.props.level.difficulty}
              level={this.props.level.level}
              readUserData={this.readUserData()}
            />
          )}
        </div>
      </div>
    </div>
  );
}

So, here we are checking if this.props.level is defined. When it is undefined React does not render anything, after getting the data LevelInfo component is rendered. You can change conditional rendering logic. You can render a Loading component maybe instead of nothing. But, at the end of the day, you will render your component conditionally.

like image 25
devserkan Avatar answered Sep 22 '22 01:09

devserkan


You need to tell your component that will wait for the data needed to render your Level component, so into your EnigmaPage component write as follow

render(){
    const { level } = this.props;
    if (!level) { return <LoadingComponentSpinner />; } // this will render only when level attr is not set, otherwise will render your `LevelInfo` component
    return (
        <div className={classes.EnigmaPage}>
            <div className={classes.Header}>
                <div>
                    <LevelInfo 
                        difficulty={this.props.level.difficulty}
                        level={this.props.level.level}
                        readUserData={this.readUserData()}
                    />

                </div>
            </div>
        </div>
    )
}

I hope it can help you.

like image 156
Juorder Gonzalez Avatar answered Sep 20 '22 01:09

Juorder Gonzalez