Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS async, wait for results

I am new to ReactJS and trying to understand it. Now I have a situation where I am loading information needed for rendering. But as it is asynchronous the component renders itself before the information is passed to it.

var info;

function getInfo() {
    //this will come from backend REST with Backbone which takes a bit
}

var InfoPage = React.createClass({
    render: function() {        
        getInfo()

        return (
            <div>info: {info}</div>            
        );
    }
});

Now the div will not show the info-value as it is not yet set in the render. So how can I have get render to wait for the info? Or how should this be solved?

The actual React.renderComponent is called from top level and that triggers all the subcomponents so I think I cannot force new render (and I shouldn't?).

like image 589
dppedro Avatar asked Jun 12 '14 12:06

dppedro


People also ask

How long does async await wait?

Async Await makes execution sequential The above takes 100ms to complete, not a huge amount of time but still slow. This is because it is happening in sequence. Two promises are returned, both of which takes 50ms to complete.

How do you wait for function to finish React?

Wait for function to finish using async/await keywords As you already know from the Promise explanation above, you need to chain the call to the function that returns a Promise using then/catch functions. The await keyword allows you to wait until the Promise object is resolved or rejected: await first(); second();

What is ASYN in React?

React Async is a promise-based library that offers a declarative API to make API calls. It provides a React component and a Hook for declarative promise resolution and data fetching. Source: https://www.npmjs.com/package/react-async.


2 Answers

You need to do something like below:

var InfoPage = React.createClass({   getInitialState: function() {      return {info: "loading ... "};   },   componentDidMount: function() {      this.getInfo();   },   render: function() {             return (         <div>info: {this.state.info}</div>                 );   },   getInfo:function(){      $.ajax({ url:"restapi/getInfo/whatever", .... }).success(function(res){         this.setState({info:res});      }.bind(this));   } }); 
like image 130
Qusai Jouda Avatar answered Nov 01 '22 05:11

Qusai Jouda


ComponentDidMount Lifecycle Method

According to the docs, componentDidMount is the component hook you should be using to do your ajax request:

http://facebook.github.io/react/docs/component-specs.html#mounting-componentdidmount

ComponentDidMount

Invoked immediately after rendering occurs... If you want to integrate with other JavaScript frameworks, set timers using setTimeout or setInterval, or send AJAX requests, perform those operations in this method.

Example

Using your example, the code might look like this:

var InfoPage = React.createClass({
  getInitialState: function () {
    return { info: {} };
  },

  componentDidMount: function () {
    $.ajax({
      url: '/info.json',
      dataType: 'json',
      success: function(data) {
        this.setState({info: data});
      }.bind(this)
    });
  },

  render: function() {        
    return (
      <div>info: {this.state.info}</div>            
    );
  }
});

getInitialState

Above, we are using the getInitialState method to return an empty info object. This allows our component to render, while we wait for the server to return with data.

Once componentDidMount executes, it will use this.setState to replace the empty info and the server data and re-render the component.

Further reading

You can see this approach used in in the Updating state section of the React tutorial.

like image 22
chantastic Avatar answered Nov 01 '22 07:11

chantastic