简体   繁体   中英

Wait until AJAX call is finished before rendering React component

Let's say I have the following code:

componentDidMount() {
    $.ajax({
        type: 'GET',
        url: '/data/',
        dataType: 'text',
        success: function(response) {
            this.setState({data: response})
        }.bind(this)
    });
}

render() {
    let {rows} = this.state.data
    return (
            <div>
                WOW
                {this.state.data}
                <FilterTable rows = {this.state.data} />
            </div>
        );
}

How can I make it so that the render() portion does not execute till ajax call is done?

Thanks!

EDIT: Fixed code.

I would rather choose a very simple approach. I will have a state named for example 'show' set value to false initially. and after the successfull ajax return in the callback will set the value of 'show' to true. and in the render mount the jsx code in the return based on the value of 'show'.

componentDidMount() {
    $.ajax({
        type: 'GET',
        url: '/data/',
        dataType: 'text',
        success: function(response) {
            this.setState({data: response, show: true});
        }.bind(this)
    });
}

render() {
    let {rows} = this.state.data
    return (
            <div>
                WOW
                {this.state.show === true : <div>
                  {this.state.data}
                  <FilterTable rows = {this.state.data} />
                </div>: null
                }

            </div>
        );
}

I am assuming you want to render the component only when the data is received . The below code snippet renders that component in the success of the ajax call. React has functions that allow us to mount a component in the DOM dynamically. You will need to import react-dom.

import ReactDOM from 'react-dom';

componentDidMount() {
  $.ajax({
    type: 'GET',
    url: '/data/',
    dataType: 'text',
    success: function(response) {
        this.setState({data: response})
        ReactDOM.render(<FilterTable rows = {response} />,document.getElementById('filterTableContainer'));
    }.bind(this)
});
}    
render() {
let {rows} = this.state.data
return (
        <div>
            WOW
            {this.state.data}
            <div id="filterTableContainer"></div>
        </div>
    );
}

You could have a boolean that toggles the display of your content and flip it in the AJAX response.

You can apply this boolean to a CSS property, or to the entire DIV content as a whole.

Below is a solution that could work. It doesn't block Render from being called, it only hides the data-dependent elements from view until the call response is received.

componentDidMount() {
    $.ajax({
        type: 'GET',
        url: '/data/',
        dataType: 'text',
        success: function(response) {
            this.setState({show: true, data: response})
        }.bind(this)
    });
}

render() {
    let {data, show} = this.state;

    let containerStyle = {
        display: show ? 'block' : 'none'
    };

    return (
            <div style={containerStyle}>
                WOW
                {this.state.pools}
                <FilterTable rows = {this.state.data} />
            </div>
        );
}

If you don't want this Component to render until the Ajax call is complete, you should question why you are loading this Component at all before the Ajax call is complete. If you want the Component to render this.state.pools regardless of whether you have this.state.data, I would recommend that your render method simple renders FilterTable conditionally.

    render() {
      let filterTable;
      if (this.state.data && this.state.data.length > 0) { // assuming an array
        filterTable = (
            <FilterTable rows = {this.state.data} />
        );
      }
      return (
        WOW
        {this.state.pools}
        {filterTable}
      );
} 

However, if you want to only render when you have this.state.data it would be better to have this Components's parent perform the Ajax call and only create this Component when the necessary information is available. In general, if you are immediately changing your Components data in componentDidMount, you should simply pass that information in as a prop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM