3

I want to Render component after AJAX call. ReactJS

import React from 'react';
import { render } from 'react-dom';
import { Card } from './components/Card';

class App extends React.Component{
    constructor(){
        super();
        this.user = [];
        console.log("constructor");
}
    componentWillMount() {
        console.log("componentWillMount 1");
               $.ajax({
                   method:'get',
                   crossDomain: true,
                   url: "http://127.0.0.1:8000/product/"
               }).done(function(res) {
                   this.user=res;
                   console.log("componentWillMount 2");

               })
    }

    render(){
        var us = this.user
        console.log("render");
        return(
            <div className="container-fluid">
                <div className="container">
                    <div className="row">
                    {(function (rows, i, len) {
                        while (i <len) {
                            rows.push(<div className="col-sm-3">
                                <Card user={us[i]}/>
                                </div>)
                                i++
                        }
                        return rows;
                    })([], 0, us.length)}
                    </div>
                </div>
            </div>
        );
    }
}
render(<App/>,window.document.getElementById("app"));

I want in this order:

  • constructor
  • componentWillMount 1
  • componentWillMount 2
  • render

but its follow like this

  • constructor
  • componentWillMount 1
  • render
  • componentWillMount 2

1 Answer 1

6

Since you have an ASYNC request, its not guranteed that the request will complete before the component renders and hence you see the current behaviour. Also since after the request completes you are setting a class variable. It doesn't cause a rerender and even when the request completes the updates won't be visible. You need to make a few changes

First: Move the ASYNC request from componentWillMount to componentDidMount since you should setState with the response from API call to cause re-render and using setState in componentWillMount doesn't trigger a re-render

Second: Make use of arrow function in the .done callback of your ajax request as you need to bind it in order to access the class properties and function

class App extends React.Component{
    constructor(){
        super();
        this.state = {user: []};
        console.log("constructor");
}
    componentDidMount() {
        console.log("componentDidMount 1");
               $.ajax({
                   method:'get',
                   crossDomain: true,
                   url: "http://127.0.0.1:8000/product/"
               }).done((res) => {
                   this.setState({user:res});
                   console.log("componentDidMount 2");

               })
    }

    render(){
        var us = this.state.user
        console.log("render");
        return(
            <div className="container-fluid">
                <div className="container">
                    <div className="row">
                    {(function (rows, i, len) {
                        while (i <len) {
                            rows.push(<div className="col-sm-3">
                                <Card user={us[i]}/>
                                </div>)
                                i++
                        }
                        return rows;
                    })([], 0, us.length)}
                    </div>
                </div>
            </div>
        );
    }
}
render(<App/>,window.document.getElementById("app"));
Sign up to request clarification or add additional context in comments.

1 Comment

Thanx Shubham Khatri

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.