关于reactjs:在react中通过父组件将数据从子组件传递到另一个子组件

pass data from child component to another child component via parent component in react

我正在学习反应并被困在一个问题上。我有 3 个组件,TransactionsDetails、TransactionForm 和 TransactionsTable。

1
2
3
TransactionsDetails
  TransactionForm
  TransactionsTable

记录保存在 TransactionsDetails 的 state.records 中,并显示在 TransactionsTable 中。我正在尝试添加、编辑、更新、删除记录。我已经成功添加了添加和删除功能,但我一直在编辑和更新。因此,在表格行中,我为每一行设置了编辑和删除按钮。单击编辑时,应在表单中加载记录数据,单击保存/提交时,应更新记录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  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">
         
            <label for="date" className="col-sm-2 control-label">Date: </label>
           
              <input type='text' name='date' className="form-control" value={this.state.date} onChange={this.handleChange}/>
           
         
         
            <label for="amount" className="col-sm-2 control-label">Amount: </label>
           
              <input type='integer' name='amount' className="form-control" value={this.state.amount} onChange={this.handleChange}/>
           
         
         
           
              <button className="btn btn-primary" type='submit'>Submit</button>
           
         
        </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 (
       
         
           
             
                <TransactionForm handleNewRecord={this.addRecord} record={this.editRecord()} />
             
           
         
         
           
             
                <TransactionsTable records={this.state.records} handleDeleteRecord={this.deleteRecord}
                handleEditRecord={this.editRecord}/>
             
           
         
       
      );
    }
  });


为了尊重您的代码风格和原创性,我根据您的代码进行编辑、删除和添加记录工作,修改较少

捕获

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
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">
        {this.props.recordToEdit.index > -1 ? 'Edit mode' : 'Create mode'}
       
          <label for="date" className="col-sm-2 control-label">Date: </label>
         
            <input type='text' name='date' className="form-control" value={this.state.date} onChange={this.handleChange}/>
         
       
       
          <label for="amount" className="col-sm-2 control-label">Amount: </label>
         
            <input type='integer' name='amount' className="form-control" value={this.state.amount} onChange={this.handleChange}/>
         
       
       
         
            <button className="btn btn-primary" type='submit'>Submit</button>
         
       
      </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 (
     
       
         
           
              <TransactionForm handleNewRecord={this.addRecord} handleUpdateRecord={this.updateRecord} recordToEdit={this.state.recordToEdit} />
           
         
       
       
         
           
              <TransactionsTable records={this.state.records} handleDeleteRecord={this.deleteRecord}
                                 handleEditRecord={this.editRecord}/>
           
         
       
     
    );
  }
});

为了使这个工作我引入 "index" 能够识别要删除或更新的记录,以及详细信息组件状态上的 recordToEdit