Hareesh
Hareesh

Reputation: 1587

ReactJS componentDidMount does not produce the value before rendering

I have the following code and getting the values through the api and set to the state variable but the view is rendered before setting the value to the state. So i could not display the value in my view. How could i change the code to work fine?

this.state = {
            activeJobs: [],
            isLoading: true
        };

componentDidMount(){

    axios.get(this.state.url+'/tables')
     .then(response => {
         // If request is good...
         const isLoading = true,
                activeJobs = response.data.activeJobs;
         this.setState({ activeJobs });
      })
     .catch((error) => {
         console.log('error ' + error);
      });
}

render() {
    console.log(this.state.activeJobs)
    <p className="text">{!this.state.isLoading && this.state.activeJobs.count} Jobs</p>
}

The console i have given inside the render shows blank array. I also tried by changing the function componentDidMount() to componentWillMount() but getting the same result.

Upvotes: 0

Views: 166

Answers (2)

Davin Tryon
Davin Tryon

Reputation: 67336

If you can't render yet, then simply return null:

render() {
    if (!this.state.activeJobs && !this.state.isLoading) {
        return null;
    }
    return (
        <div>
            { this.state.isLoading && <p className="text">Loading...</p> }
            { !this.state.isLoading && <p className="test">{ this.state.activeJobs.count } Jobs</p>
        </div>
    );
}

In order to set isLoading, set it before the HTTP call:

componentDidMount(){

    this.setState({ isLoading: true });
    axios.get(this.state.url+'/tables')
     .then(response => {
         // If request is good...
         const activeJobs = response.data.activeJobs;
         this.setState({ activeJobs, isLoading: false });
      })
     .catch((error) => {
         console.log('error ' + error);
      });
}

Upvotes: 0

Yossi
Yossi

Reputation: 6027

There is no way to ensure that an async request will complete before rendering. You can display proper messages in render to reflect the status of the request.

For example - before calling axios, set the state to 'in process' or 'loading', so that render will show an appropriate message. Then, when loading finished successfully or with an error, set the state appropriately to render an appropriate message in the error case, and the result otherwise.

Upvotes: 2

Related Questions