Worker Worker - 2 months ago 22
React JSX Question

Empty state value for initial call in reactJs

When the initial call is made the value is fetched using the api from the server but when I set the value to a state initially it is coming empty but from next iteration value is getting coming fine. What is reason behind this and how to overcome this. Below is the code for the same. Variable sampleData[0] value is coming empty and rest value of the array is coming as NaN as per the code.

var sampleData = [];
var Sample = React.createClass({

getInitialState: function() {
return { resValue : {} };
},

componentDidMount: function(){
this.update();
},

update: function(){
new plotMovingLine( document.getElementById("movingLine"),[[0]], lineOptions);
this.getRandomData();
setTimeout(this.update, 2000);
},

getRandomData: function() {

var value=0,cal=0;
this.getData();

console.log(this.state.resValue); //Initial object value displaying empty

if(sampleData.length == 0 )
{ sampleData[0]=this.state.resValue;
console.log(sampleData[0]); }
else{
value=sampleData[sampleData.length-1].val;
cal= this.state.resValue.val-value;
sampleData.push({"val":cal});
}
},

getData: function(){
this.serverRequest = $.get("http://localhost:8088/data", function(data) {
this.setState({
resValue: data
});
}.bind(this));
},

render: function() {
//view
}
});


Below is the image from the console of the above code.

Image

Answer

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

Execute whatever you want to after the setState has mutated by writing that in a callback function.

var sampleData = [];
var Sample = React.createClass({

   getInitialState: function() {
        return {  resValue : {} };
     }, 

    componentDidMount: function(){
            this.update();                                               
    },

    update: function(){
            new plotMovingLine( document.getElementById("movingLine"),[[0]], lineOptions);
                this.getRandomData();
         setTimeout(this.update, 2000);
   },

    getRandomData: function() {

         var value=0,cal=0;
         this.getData();                


   },

   getData: function(){         
        this.serverRequest = $.get("http://localhost:8088/data", function(data) {                                                       
                this.setState({
                            resValue: data
                }, function(){
                    console.log(this.state.resValue);  //Initial object value displaying empty

         if(sampleData.length == 0 )
       {    sampleData[0]=this.state.resValue; 
            console.log(sampleData[0]);  }
            else{   
                    value=sampleData[sampleData.length-1].val;
                    cal= this.state.resValue.val-value;
                    sampleData.push({"val":cal});        
            }
                });
            }.bind(this));             
   },

   render: function() {
       //view 
        }
});

A second option is that whenever setState() completes, render() is called again. So you can create a function for whatever you want to do with the state data and then call that function in render()

Comments