我想在一个组件中访问另一个组件的状态,我该怎么做

时间:2017-05-31 07:34:41

标签: javascript jquery reactjs bootstrap-4

我想访问我的daterangepicker组件的状态到barchartcomponent,我在仪表板组件中调用我的daterangepicker组件如何在barchartcomponent的查询URL中获取dateranpicker组件的状态 这是我的代码可以任何人帮助 DateRangePickerComponent.jsx

class DaterangePickerComponent extends React.Component
{

    constructor(props) 
    {
        super(props);
        this.state = 
        {
            startDate:null,
            endDate:null
        }
    };

    componentDidMount()
    {
        var that =this;
        $(document).ready(function(){
        $("#dp").daterangepicker(
        {   timePicker: true,
            timePickerIncrement: 30,
            locale: {
            format: 'MM/DD/YYYY h:mm A'
            },
            ranges: {
               'Today': [moment(), moment()],
               'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
               'Last 7 Days': [moment().subtract(6, 'days'), moment()],
               'Last 30 Days': [moment().subtract(29, 'days'), moment()],
               'This Month': [moment().startOf('month'), moment().endOf('month')],
               'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
               'Last 60 Days': [moment().subtract(59, 'days'), moment()],
               'Last 90 Days': [moment().subtract(89, 'days'), moment()]
                }
            });
        }).on('change', function(){
            var v = $("#dp").val().toString().split("-");
            that.setState({ startDate:v[0],endDate:v[1]});
        });

    }

    render()
    {
        return (
        <div className="form-group has-feedback">
            <div className='input-group add-on col-md-2 date datepicker' data-date-format="yyyy-mm-dd">
                <input id="dp" type="text" className="form-control date-picker" data-date-format="yyyy-mm-dd" value="DaterangePicker"/>
                <span className="input-group-addon"><span className="glyphicon-calendar glyphicon"></span></span>
            </div>

        </div>
        );
    }
}
window.DaterangePickerComponent = DaterangePickerComponent;

BarChartComponent.jsx

class BarChartComponent extends React.Component 
{

   constructor(props) 
   {
      super(props);

      this.state = {
         data: null,
         xlabel:null,
         ylabel:null
      }
   };

   componentDidMount()
    {
            var that = this;
            $.ajax({
                    method: "GET",
                    url: "/querydata?query_id="+that.props.id+"&start_time="+that.props.starttime +"&end_time="+that.props.endtime,
                    success: function(data) 
                    {

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

    componentDidUpdate(prevProps, prevState)
    {

        var that = this;
        if( _.isEqual(prevState.data , that.state.data ))
            {
                if(prevProps.id !== that.props.id)
                {
                    $.ajax({
                    method: "GET",
                    url: "/querydata?query_id="+that.props.id+"&start_time="+that.props.starttime +"&end_time="+that.props.endtime,
                    success: function(data) 
                    {
                        console.log("component did update method called");
                        var BarChartData  = [
                        {
                            key: "totals",
                            values: []
                        }
                        ];
                        data['data'].forEach(function (d)
                        {
                            d.value= +d.value
                            BarChartData[0].values.push(d)
                        })                                                  
                        if( _.isEqual(prevState.data , that.state.data ))
                        {
                            that.setState({data:BarChartData}); 
                        }                   
                    },
                    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" yAxis={{
             axisLabel:this.state.ylabel}} xAxis={{ axisLabel:this.state.xlabel}} />

        );
    }
}

window.BarChartComponent = BarChartComponent;

Dashboard.jsx

class Dashboard extends React.Component 
    {

        constructor(props) 
        {
            super(props);

            this.state =
            {
                all_dashboards:null,
                current_dashboard: null,
                link:[]

            }
            this.updateDashboardState = this.updateDashboardState.bind(this);
            this.updatecharts = this.updatecharts.bind(this);
        };

        componentDidMount()
        {
            var that = this;
            $.ajax({
                        method: "GET",
                        url: "/dashboarddata",
                        dataType: "json",
                        success: function(data) 
                        {
                            console.log(1,JSON.stringify(data));
                            console.log(2,data);
                            that.setState({all_dashboards:data['data'], current_dashboard:data['data'][0]['Charts']});
                            var Link_Tab =[];
                            var keys = Object.keys(data['data']);
                            keys.forEach(function(key)
                            {
                                console.log(data['data'][key]['link']);
                                Link_Tab.push(data['data'][key]['link']);
                            }); 
                            that.setState({link:Link_Tab});
                        },
                        error: function(XMLHttpRequest, textStatus, errorThrown)
                        { 
                            console.error("Status: " + textStatus);
                            console.error("Error: " + errorThrown); 
                        }       
                    });                 
        }

        updateDashboardState(index)
        {
            if( (this.state.current_dashboard) == null && (this.state.all_dashboards) == null )
            {
                return (<h1>Loading..</h1>)
            }
            else
            {   

                this.setState({current_dashboard:this.state.all_dashboards[index]['Charts']})

            }
        }

        updatecharts(chart)
        {

            if((chart.type)=="MetricChartComponent")
                {

                    return <MetricChartComponent id ={chart.query_id} />;
                }
            else if((chart.type)=="BarChartComponent" )
                {

                    return <BarChartComponent id ={chart.query_id} />;
                }
            else if((chart.type)=="PieChartComponent")
                {

                     return <PieChartComponent id ={chart.query_id} />;
                }
            else if((chart.type)=="LineChartComponent")
                {

                    return <LineChartComponent id ={chart.query_id} />;
                }
            else if((chart.type)=="TableChartComponent")
                {

                    return <TableChartComponent id={chart.query_id} />;
                }
            else
                {

                    return (<h1> Not a valid type chart </h1>); 
                }
        }

        render() 
        {
            var that =this;
            console.log(3,this.state.current_dashboard);
            console.log(4,this.state.link);
            if(this.state.current_dashboard==null)
            {
                    return (<h1>Loading..</h1>);
            }
            return (

                    <div>

                        <div align="row">

                                    <ul className="nav nav-tabs">
                                        {this.state.link.map(function(name,index)
                                        {
                                            return <li role="presentation" id ="myid" onClick={()=>{that.updateDashboardState(index)}} ><a href="#" >{name}</a></li>
                                        })}
                                    </ul>
                        </div>

                        <DaterangePickerComponent starttime ={this.state.startDate} endtime={this.state.endDate}/>

                        <div className ="row" >
                            {this.state.current_dashboard.map(function(chart)
                                {
                                    return(

                                            <div className="col-sm-6">
                                                <div className="panel panel-default ">
                                                    <div className="panel-heading">
                                                            <h3 className="panel-title">{chart.title}</h3>
                                                    </div>
                                                    <div className="panel-body">

                                                            { that.updatecharts(chart) }                                        

                                                    </div>
                                                </div>
                                            </div>


                                          );
                                })
                            } 
                        </div>

                    </div>  
                );
        }
    }

window.Dashboard = Dashboard;

1 个答案:

答案 0 :(得分:0)

React是一种单向数据流框架,按照设计,组件无法访问另一个组件的内部状态。

我强烈建议您考虑使用reduxmobX等全球状态商店。

如果您只想使用React,最好的办法是让日期选择器成为受控组件。换句话说,使日期选择器成为无状态组件,让状态向上游流向仪表板。渲染日期选择器时,传入2个回调。

<DaterangePickerComponent 
    onStartDateChange={function(newStartDate)...} 
    onEndDateChange{function(newEndDate)...} 
    starttime={this.state.startDate}
    endtime={this.state.endDate}
/>

在日期选择器组件的实现中,将此调用替换为setState

that.setState({ startDate:v[0],endDate:v[1]});

调用我们现在作为道具传递的onStartDateChangeonEndDateChange处理程序。

请注意,在此方案中,您的starttimeendtime道具不仅代表日期选择器的初始状态,还代表其始终显示的值。