草庐IT

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

codeneng 2023-03-28 原文

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}/>
             
           
         
       
      );
    }
  });

  • 那么你被困在哪里了?你期望会发生什么?目前正在发生什么?
  • 不确定是否有人向您提到过,但为了让这种事情变得更容易 Facebook(以及许多其他使用 React 的人)使用某种 Flux 实现来尝试优雅地解决这个问题。
  • @BenHare 感谢您的提示。我是 React 的新手。无论如何,当我得到这个工作时,我会尝试以"通量"的方式来做。顺便说一句,您能否指出以正确方式解决上述问题的任何链接?谢谢。
  • @gravityplanx 目前,当我单击编辑按钮时,记录(要编辑)被传递给 TransactionsDetails 中定义的 editRecord 函数。从那里,它需要被加载到 TransactionForm 中并且应该能够被更新。
  • 这是 Facebook 对 Flux 是什么以及他们为什么使用它的解释,应该是一个好的开始:facebook.github.io/flux/docs/overview.html


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

捕获

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

有关关于reactjs:在react中通过父组件将数据从子组件传递到另一个子组件的更多相关文章

  1. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  2. ruby-on-rails - Rails - 从另一个模型中创建一个模型的实例 - 2

    我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案

  3. ruby - 一个 YAML 对象可以引用另一个吗? - 2

    我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的ruby​​yaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir

  4. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  5. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  6. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  7. ruby - 将一个超薄文件包含在另一个超薄文件中 - 2

    我在一个静态网站上工作(因此没有真正的服务器支持),我想在另一个网站中包含一个小的细长片段,可能会向它传递一个变量。这可能吗?在rails中很容易,虽然是render方法,但我不知道如何在slim上做(显然load方法不适用于slim)。 最佳答案 Slim包含Include插件,允许在编译时直接在模板文件中包含其他文件:require'slim/include'includepartial_name文档可在此处获得:https://github.com/slim-template/slim/blob/master/doc/incl

  8. ruby-on-rails - 如何使用 ruby​​ 从 self 方法调用另一个方法? - 2

    #app/models/product.rbclassProduct我从Controller调用方法1。当我运行程序时。我收到一个错误:method_missing(atlinemethod2(param2)).rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0/lib/active_record/relation/batches.rb:59:in`block(2levels)infind_each... 最佳答案 classProduct说明:第一个是类

  9. ruby - 如何将 Puma::Configuration 传递给 Sinatra? - 2

    这是我的网络应用:classFront我是这样开始的(请不要建议使用Rack):Front.start!这是我的Puma配置对象,我不知道如何传递给它:require'puma/configuration'Puma::Configuration.new({log_requests:true,debug:true})说真的,怎么样? 最佳答案 配置与您运行的方式紧密相关puma服务器。运行的标准方式puma-pumaCLI命令。为了配置puma配置文件config/puma.rb或config/puma/.rb应该提供(参见examp

  10. jquery - 如何将 AJAX 变量从 jQuery 传递到他们的 Controller ? - 2

    我有一个电子邮件表格。但是我正在制作一个测试电子邮件表单,用户可以在其中添加一个唯一的电子邮件,并让电子邮件测试将其发送到该特定电子邮件。为了简单起见,我决定让测试电子邮件通过ajax执行,并将整个内容粘贴到另一个电子邮件表单中。我不知道如何将变量从我的HAML发送到我的Controllernew.html.haml-form_tagadmin_email_blast_pathdoSubject%br=text_field_tag'subject',:class=>"mass_email_subject"%brBody%br=text_area_tag'message','',:nam

随机推荐