React js - 在ajax调用后更新表行

时间:2016-08-18 19:20:55

标签: reactjs

我无法弄清楚下面的代码有什么问题。单击“提交”按钮后,表行永远不会更新。

我认为在manipulateData()中的this.setState({data:arr})可以做到,但事实并非如此。

非常感谢任何帮助。谢谢。

/*
v1.0
*/

var cols = [
    { key: 'sessionid1', label: 'Session 1' },
    { key: 'type', label: 'Type' },
    { key: 'sessionid2', label: 'Session 2' }
];

var data = [
    { id: 1, sessionid1: 'acb20dc0', type: 'CLIENT', sessionid2: 'acb20dc0' },
    { id: 2, sessionid1: 'acb20dc0', type: 'CLIENT', sessionid2: 'acb20dc0' },
    { id: 3, sessionid1: 'acb20dc0', type: 'SERVER', sessionid2: 'acb20dc0' },
    { id: 4, sessionid1: 'acb20dc0', type: 'CLIENT', sessionid2: 'acb20dc0' }
];

var Logviewer = React.createClass({
    getInitialState: function() {
        return {
            text: '', 
            kibana: false,
            data: [],
            cols: cols
        };
    },

    render: function(){
        return(
            <div>
                <div className="row header">
                  <Header 
                    text={this.state.text} 
                    kibana={this.state.kibana}
                    />
                </div>

                <div className="row">
                  <TabularData cols={this.props.cols} data={this.state.data} />
                  <Graphic />
                </div>
            </div>
        );
    }
});

var Header = React.createClass({
    handleSubmit: function(){
        console.log('submit - ', this.state.data);
        $.ajax({
              url: 'http://10.164.98.27:7474/db/data/cypher',
              dataType: 'json',
              type: 'POST',
              data: this.state.queryData,
              success: function(data) {
                console.log('data: ', data);
                // manipulate data first to correct format
                this.manipulateData(data);
              }.bind(this),
              error: function(xhr, status, err) {
                //this.setState({data: this.state.data});
                console.error(this.props.url, status, err.toString());
          }.bind(this)
      });    
  },

  manipulateData: function(obj){
      console.log('manipulateData');
      var arr = [];
      for(var i = 0; i < obj.data.length; i++){
          //console.log('size: ', i);
          arr.push({id: i, sessionid1: obj.data[i][0].data.sessionid, type: obj.data[i][1], sessionid2: obj.data[i][2].data.sessionid});      
      }
      console.log('manipulated obj: ', arr);
      this.setState({data: arr});// this was supposed to update the table content but doesn't
      $('#tabularDataTable').show();
  },

  handleCheckbox: function(){
      if($('#leftHandSide').is(':visible')){
          $('#leftHandSide, #rightHandSide').hide();
      }
      else{
          $('#leftHandSide, #rightHandSide').show();
      }
  },

  handleSessionIdChange: function(e){
      console.log('sessionId: ', e.target.value);
      var query = {
              "query" : "MATCH (a {sessionid : '" + e.target.value + "'})-[r*]-(b) UNWIND r AS rel RETURN distinct startNode(rel) AS a, type(rel), endNode(rel) AS b",
              "params" : { }
      }
      this.setState({queryData: query});
  },

  render: function() {
      return (
        <div className="columns small-12">
            <div className="columns small-2 logo">
              <img src="../images/247ToolsLogo.png" className="tools-logo" title="247 tools logo" />
            </div>
            <div className="columns small-2 tool-name">Log Viewer</div>
            <div className="columns small-8 search">
                <form className="sessionIdForm">
                    <input
                      type="text"
                      placeholder="Session Id"
                      //defaultValue={this.state.text}
                      defaultValue={this.props.text}
                      onBlur={this.handleSessionIdChange}
                    />
                    <a href="#" id="submit" onClick={this.handleSubmit} className="button">Find related session ids</a>
                    <div id="kibana"><input type="checkbox" id="kibanaCheckbox" checked={this.props.kibana} onClick={this.handleCheckbox} /><label htmlFor="kibanaCheckbox">Redirect to Kibana</label></div>
                </form>
            </div>
        </div>
      );
  }
});

var TabularData = React.createClass({
    render: function(){
        console.log('TabularData - 1');
        return(
            <div className="columns small-6" id="leftHandSide">
              <h4>Table View</h4>
              <Table cols={this.props.cols} data={this.props.data} />
            </div>
        );
    }
});

var Table = React.createClass({
    render: function() {
        console.log('Table - render');
        var headerComponents = this.generateHeaders(),
            rowComponents = this.generateRows();

        return (
            <table id="tabularDataTable">
                <thead>{headerComponents}</thead>
                <tbody>{rowComponents}</tbody>
            </table>
        );
    },

    generateHeaders: function() {
        var cols = this.props.cols;  // [{key, label}]

        // generate our header (th) cell components
        return cols.map(function(colData) {
            return <th key={colData.key}>{colData.label}</th>;
        });
    },

    generateRows: function() {
        var cols = this.props.cols,  // [{key, label}]
            data = this.props.data;

        return data.map(function(item) {
            // handle the column data within each row
            var cells = cols.map(function(colData, i) {
                if(i === 0 || i === 2){
                  return <td key={i}><a target="_blank" href={"https://logview01.pool.sv2.247-inc.net/#/discover?time:(from:now-30d,mode:quick,to:now))&amp;_a=(columns:!(_source),index:'logstash-shared-services-*',interval:auto,query:(query_string:(analyze_wildcard:!t,query:&quot;" + item[colData.key] + "&quot;)),sort:!('@timestamp',desc))&amp;_g=(refreshInterval:(display:Off,pause:!f,section:0,value:0),time:(from:now-30d,mode:quick,to:now))"}>{item[colData.key]}</a></td>;
                }
                else{
                  return <td key={i}>{item[colData.key]}</td>;
                }
            });
            return <tr key={item.id}>{cells}</tr>;
        });
    }
});

var Graphic = React.createClass({
    render: function(){
        return(
          <div className="columns small-6" id="rightHandSide">
              <h4>Graphic View</h4>
          </div>
        );    
    }
});

ReactDOM.render(
    <Logviewer data={data} cols={cols} />,
    document.getElementById('content')
);

1 个答案:

答案 0 :(得分:1)

问题是您正在为Header组件设置状态。所以会发生的情况是,LogViewer拥有包含一组数据的自己的状态,而您的Header也拥有自己拥有一组数据的状态。由于TabularData组件从LogViewer的状态(通过道具)获取数据,因此它永远不会知道有关更新数据的任何信息。

您可以通过几种不同的方式解决这个问题。一种方法是将数据提取和setState调用移至LogViewer。另一种方法是将回调函数作为道具传递给Header中的LogViewer组件,如下所示:

<Header
  text={this.state.text} 
  kibana={this.state.kibana}
  onDataFetch={(data) => { this.setState({ data }) }
/>

然后,在Header组件中,您拨打this.props.onDataFetch(arr)而不是this.setState({data: arr})