1

I am currently making dashboards using reactjs in which there are 4 tabs or buttons charts are creating properly but only problem is that when we click on different dashboard and it has same chart in same pannel than chart is not updating i have used both componentDidMount() and componentDidUpdate though its giving proper output but its creating an infinite loop i have also applied some conditions but its still in infinite loop Can anyone help me??

here is my code

class BarChartComponent extends React.Component 
{

   constructor(props) 
   {
      super(props);

      this.state = {
         data: null
      }
   };

   componentDidMount()
    {
            var that = this;
            $.ajax({
                    method: "GET",
                    url: "http://10.0.3.8:8050/querydata?query_id="+that.props.id,
                    success: function(data) 
                    {

                        console.log("component did mount method called");
                        console.log(1,JSON.stringify(data));
                        var BarChartData  = [
                        {
                            key: "totals",
                            values: []
                        }
                        ];
                        data.forEach(function (d)
                        {
                            d.value= +d.value
                            BarChartData[0].values.push(d)
                        }) 
                        console.log(2,JSON.stringify(BarChartData))
                        that.setState({data:BarChartData});
                    },
                    error: function(XMLHttpRequest, textStatus, errorThrown)
                    { 
                        console.error("Status: " + textStatus);
                        console.error("Error: " + errorThrown); 
                    }       
                });         
    }

    componentDidUpdate(prevProps, prevState)
    {
                if(prevState.data !== this.state.data )
                {
                    var that = this;
                    $.ajax({
                        method: "GET",
                        url: "http://10.0.3.8:8050/querydata?query_id="+that.props.id,
                        success: function(data) 
                        {

                            console.log("component did update method called");
                            var BarChartData  = [
                            {
                                key: "totals",
                                values: []
                            }
                            ];
                            data.forEach(function (d)
                            {
                                d.value= +d.value
                                BarChartData[0].values.push(d)
                            }) 

                            if( prevProps.id !== that.state.id )
                            {
                                that.setState({data:BarChartData});
                                console.log(3,JSON.stringify(BarChartData))
                                console.log(4,JSON.stringify(that.state.data))
                            }                   
                        },
                        error: function(XMLHttpRequest, textStatus, errorThrown)
                        { 
                            console.error("Status: " + textStatus);
                            console.error("Error: " + errorThrown); 
                        }       
                    });         

                }
    }



    render()
    {

        if (this.state.data==null)
        {
            return (<h1>Loading...</h1>);
        }
        return (


             <NVD3Chart type="discreteBarChart" datum={this.state.data} x="name" y="value"/>

        );
    }
}

window.BarChartComponent = BarChartComponent;
rishabhjitani
  • 321
  • 1
  • 4
  • 9

2 Answers2

3

if(prevState.data !== this.state.data) doesn't compare the actual object for equality. That's why I assume your $.ajax request is fired continously in componentDidUpdate, even though the actual data is the same.

If you really want to go the expensive way you could use lodash (_.isEqual) to compare the objects (or the built-in method in jQuery). Eventually it's a better approach to compare specific data for performance reasons, though.

blizzard
  • 5,275
  • 2
  • 34
  • 48
Severin
  • 308
  • 1
  • 11
  • 1
    Thanks for your i have used lodash for comparison and its working – rishabhjitani May 16 '17 at 11:25
  • Thank you the isEqual comparison worked for me, I added only the isEqual function in lodash instead of the entire lib, to avoid bloating file size https://stackoverflow.com/a/35251059/8926452 – Anaizing Oct 26 '18 at 19:39
0

I think there is better to use this check in top part of componentDidUpdate:

if (prevProps.id !== this.props.id)

as your request only depends on this parameter.

Then you won't have infinite loop, as id has scalar value and equality check will work.

lunochkin
  • 684
  • 4
  • 17