通过反应中的父组件将数据从子组件传递到另一个子组件

时间:2016-06-03 19:16:53

标签: reactjs

我正在学习反应并陷入困境。我有3个组件,TransactionsDetails,TransactionForm和TransactionsTable。

TransactionsDetails
  TransactionForm
  TransactionsTable

记录保存在TransactionsDetails的state.records中,并显示在TransactionsTable中。我正在尝试添加,编辑,更新,删除记录。我已经成功添加了添加和删除功能,但我仍然坚持编辑和更新。因此,在表格行中,我有每行的编辑和删除按钮。点击编辑时,它应该在表格中加载记录数据,当点击保存/提交时,它应该更新记录。

  var TransactionForm = React.createClass({
    getInitialState: function(){
      return { date: '', amount: '' };
    },

    handleChange: function(e){
      switch(e.target.name){
        case 'date':
          this.setState({date: e.target.value});
          break;
        case 'amount':
          this.setState({amount: e.target.value});
          break;
      }
    },

    handleSubmit: function(e){
      e.preventDefault();
      this.props.handleNewRecord(this.state);
      this.setState(this.getInitialState());
    },

    render: function(){
      return (
        <form onSubmit={this.handleSubmit} className="form-horizontal">
          <div className="form-group">
            <label for="date" className="col-sm-2 control-label">Date: </label>
            <div className="col-sm-10">
              <input type='text' name='date' className="form-control" value={this.state.date} onChange={this.handleChange}/>
            </div>
          </div>
          <div className="form-group">
            <label for="amount" className="col-sm-2 control-label">Amount: </label>
            <div className="col-sm-10">
              <input type='integer' name='amount' className="form-control" value={this.state.amount} onChange={this.handleChange}/>
            </div>
          </div>
          <div className="form-group">
            <div className="col-sm-offset-2 col-sm-10">
              <button className="btn btn-primary" type='submit'>Submit</button>
            </div>
          </div>
        </form>
      );
    }
  });

  var TransactionRow = React.createClass({
    handleDelete: function(e){
      e.preventDefault();
      this.props.handleDeleteRecord(this.props.record);
    },

    handleEdit: function(e){
      e.preventDefault();
      this.props.handleEditRecord(this.props.record);
    },

    render: function(){
      return (
        <tr>
          <td>{this.props.record.date}</td>
          <td>{this.props.record.amount}</td>
          <td>
            <button className="btn btn-primary" onClick={this.handleEdit}>Edit</button>
            <button className="btn btn-danger" onClick={this.handleDelete}>Delete</button>
          </td>
        </tr>
      );
    }
  });

  var TransactionsTable = React.createClass({
    render: function(){
      var rows = [];
      this.props.records.map(function(record, index){
      rows.push(<TransactionRow key={index} record={record} handleDeleteRecord={this.props.handleDeleteRecord}
        handleEditRecord={this.props.handleEditRecord}/>);
      }.bind(this));
      return (
        <table className="table table-striped table-hover table-bordered">
          <thead>
            <tr>
              <th> Date </th>
              <th> Amount </th>
              <th> Actions </th>
            </tr>
          </thead>
          <tbody>
            { rows }
          </tbody>
        </table>
      );
    }
  });

  var TransactionsDetails = React.createClass({
    getInitialState: function(){
      return { records: [
        { date: '1-6-2016', amount: 1000},
        { date: '2-6-2015', amount: -400}
      ] };
    },

    addRecord: function(record){
      var records = this.state.records;
      records.push(record);
      this.setState({ records: records });
    },

    deleteRecord: function(record){
      var records = this.state.records;
      var index  = records.indexOf(record);
      records.splice(index, 1);
      this.setState({ records: records });
    },

    editRecord: function(record){
      if(record){
          return record;
        } else {
          return {};
        }
    },

    render: function(){
      return (
        <div className="container">
          <div className='row'>
            <div className="col-md-4">
              <div className="well">
                <TransactionForm handleNewRecord={this.addRecord} record={this.editRecord()} />
              </div>
            </div>
          </div>
          <div className='row'>
            <div className="col-md-offset-2 col-md-8">
              <div className="well">
                <TransactionsTable records={this.state.records} handleDeleteRecord={this.deleteRecord}
                handleEditRecord={this.editRecord}/>
              </div>
            </div>
          </div>
        </div>
      );
    }
  });

1 个答案:

答案 0 :(得分:1)

我根据您的代码进行编辑,删除和添加记录,少做修改以尊重您的代码风格和原始

capture

var TransactionForm = React.createClass({
  getInitialState: function(){
    return { date: '', amount: '' };
  },

  handleChange: function(e){
    switch(e.target.name){
      case 'date':
        this.setState({date: e.target.value});
        break;
      case 'amount':
        this.setState({amount: e.target.value});
        break;
    }
  },

  componentWillReceiveProps: function(nextProps) {
    if(nextProps.recordToEdit.index != this.props.recordToEdit.index) {
      this.setState(nextProps.recordToEdit.record)
    }
  },

  handleSubmit: function(e){
    e.preventDefault();
    if(this.props.recordToEdit.index > -1) {
      this.props.handleUpdateRecord(this.props.recordToEdit.index, this.state);
    } else {
      this.props.handleNewRecord(this.state);
    }
    this.setState(this.getInitialState());
  },

  render: function(){
    return (
      <form onSubmit={this.handleSubmit} className="form-horizontal">
        <div>{this.props.recordToEdit.index > -1 ? 'Edit mode' : 'Create mode'}</div>
        <div className="form-group">
          <label for="date" className="col-sm-2 control-label">Date: </label>
          <div className="col-sm-10">
            <input type='text' name='date' className="form-control" value={this.state.date} onChange={this.handleChange}/>
          </div>
        </div>
        <div className="form-group">
          <label for="amount" className="col-sm-2 control-label">Amount: </label>
          <div className="col-sm-10">
            <input type='integer' name='amount' className="form-control" value={this.state.amount} onChange={this.handleChange}/>
          </div>
        </div>
        <div className="form-group">
          <div className="col-sm-offset-2 col-sm-10">
            <button className="btn btn-primary" type='submit'>Submit</button>
          </div>
        </div>
      </form>
    );
  }
});

TransactionForm.defaultProps = {
  recordToEdit: { index: -1, record: {}}
};

var TransactionRow = React.createClass({
  render: function(){
    return (
      <tr>
        <td>{this.props.record.date}</td>
        <td>{this.props.record.amount}</td>
        <td>
          <button className="btn btn-primary" onClick={this.props.handleEditRecord}>Edit</button>
          <button className="btn btn-danger" onClick={this.props.handleDeleteRecord}>Delete</button>
        </td>
      </tr>
    );
  }
});

var TransactionsTable = React.createClass({
  render: function(){
    var rows = this.props.records.map(function(record, index){
      return <TransactionRow key={index} record={record} handleDeleteRecord={() => this.props.handleDeleteRecord(index)}
                                handleEditRecord={() => this.props.handleEditRecord(index, record)}/>;
    }.bind(this));
    return (
      <table className="table table-striped table-hover table-bordered">
        <thead>
        <tr>
          <th> Date </th>
          <th> Amount </th>
          <th> Actions </th>
        </tr>
        </thead>
        <tbody>
        { rows }
        </tbody>
      </table>
    );
  }
});

var TransactionsDetails = React.createClass({
  getInitialState: function(){
    return {
      records: [
        { date: '1-6-2016', amount: 1000},
        { date: '2-6-2015', amount: -400}
      ],
      recordToEdit: {
        index: -1,
        record: {}
      }
    };
  },

  addRecord: function(record){
    var records = this.state.records;
    records.push(record);
    this.setState({ records: records });
  },

  deleteRecord: function(index){
    console.log(index)
    var records = [].concat(this.state.records);
    records.splice(index, 1);
    this.setState({ records: records });
  },

  updateRecord: function(index, record){
    var records = [].concat(this.state.records)
    records[index] = record;
    this.setState({ records: records });
  },

  editRecord: function (index, record) {
    this.setState({
      recordToEdit: {
        index: index,
        record: record
      }
    })
  },

  render: function(){
    return (
      <div className="container">
        <div className='row'>
          <div className="col-md-4">
            <div className="well">
              <TransactionForm handleNewRecord={this.addRecord} handleUpdateRecord={this.updateRecord} recordToEdit={this.state.recordToEdit} />
            </div>
          </div>
        </div>
        <div className='row'>
          <div className="col-md-offset-2 col-md-8">
            <div className="well">
              <TransactionsTable records={this.state.records} handleDeleteRecord={this.deleteRecord}
                                 handleEditRecord={this.editRecord}/>
            </div>
          </div>
        </div>
      </div>
    );
  }
});

为了使这个工作,我介绍&#34;索引&#34;能够识别要删除或更新的记录,以及详细信息组件状态的recordToEdit