Camper Leaderboard problem

I don’t understand in which order React renders and executes functions… Where should I put promise to fetch data and setState in order to work? I tried in componentDidMount but it gives me an error because I guess when App component is rendered the state is still empty. Should I use different lifecycle method?


class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      data: []
    }
  }

  componentDidMount() {
    axios.get('https://fcctop100.herokuapp.com/api/fccusers/top/recent')
      .then((res) => {
        this.setState({ data: res.data });
      });
  }

  render() {
    return (
      <div className="App">
        <div className="wrapper">
          <div className="header">
            <p>FreeCodeCamp Leaderboard</p>
          </div>
          <Headings/>
          <User data={this.state.data}/>
        </div>
      </div>
    );
  }
};

class User extends Component {
  render() {
    return (
      <div className="user">
        <div className="number">1</div>
        <div className="camper-name">{this.props.data[0].username}</div>
        <div className="thirty-days-points">{this.props.data[0].recent}</div>
        <div className="all-time-points">{this.props.data[0].alltime}</div>
      </div>
    );
  }
}

wait for this.state.data to be filled before rendering because your class will be rendering even before componentDidMount() has finished pulling the data,

for example your render function could look like this:

render() {
  if(this.state.data.length){
    return (
      <div className="App">
        <div className="wrapper">
          <div className="header">
            <p>FreeCodeCamp Leaderboard</p>
          </div>
          <Headings/>
          <User data={this.state.data}/>
        </div>
      </div>
    );
}
else{
   return (<div> I'm still waiting on data !!</div>)
}

  }

Option 2: provide a specific clause in componentDidUpdate(prevProps, prevState) , this option by default renders every time there is a state change, but you can manually control the rendering by for example setting a boolean flag in this function and comparing previous props / states with current props/states.

1 Like

How stupid I am… I will try the second option too, thanks for help!