React JS:如何从父组件访问子组件的状态对象

时间:2018-11-07 21:21:08

标签: javascript reactjs

我是ReactJs的新手,我在这里附加相同的代码。我有3个组成部分,分别是地址,电话和电子邮件。带地址的表单是父组件。电话和电子邮件是表单的子组件,我无法从父组件访问电话和电子邮件的状态对象,我知道如何将父状态对象发送给子组件,但是相反,我不知道它,我尝试了回调等等,但这没有帮助。请提供您的输入。

import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    import {
      Panel,
      Button,
      Col,
      PageHeader,
      ControlLabel,
      FormControl,
      HelpBlock,
      FormGroup,
      Checkbox,
      Form,
      Radio,
      InputGroup,
      Glyphicon } from 'react-bootstrap';

    import FormControlFeedback from 'react-bootstrap/lib/FormControlFeedback';
    import FormControlStatic from 'react-bootstrap/lib/FormControlStatic';
    import InputGroupAddon from 'react-bootstrap/lib/InputGroupAddon';
    import Email from './Email';
    import Phone from './Phone';

    const spacing = {
      marginRight: "20px",
      marginbottom: "20px"
    }
    const buttonalignment = {
      marginLeft: "81px",
      marginbottom: "20px"
    }




    class displayForms extends React.Component {

      constructor(props) {
        super(props);

        //  this.state.products = [];
        this.state = {};
        this.state.filterText = "";
        this.state.products = [
          {
            id: 1,
          Field1: "",
           Field2: '',
           Field3: '',
           Field4: '',
           Field5:'',
           Field6: '',
           Field7: ''
          }
        ];

      }
      handleUserInput(filterText) {
        this.setState({filterText: filterText});
      };
      handleRowDel(product) {
        var index = this.state.products.indexOf(product);
        this.state.products.splice(index, 1);
        this.setState(this.state.products);
      };

      handleAddEvent(evt) {
        var id = (+ new Date() + Math.floor(Math.random() * 999999)).toString(36);
        var product = {
          id: id,
          Field1: "",
           Field2: '',
           Field13: '',
           Field14: '',
           Field5:'',
           Field6: '',
           Field7: ''

        }
        this.state.products.push(product);
        this.setState(this.state.products);

      }

      handleProductTable(evt) {
        var item = {
          id: evt.target.id,
          name: evt.target.name,
          value: evt.target.value
        };
        console.log('item.value[0] in address',item.value);
        console.log('item.value[1] in address',item.value);
        console.log('item.value[2] in address',item.value);
    var products = this.state.products.slice();
      var newProducts = products.map(function(product) {

        for (var key in product) {
          if (key == item.name && product.id == item.id) {
            product[key] = item.value;

          }
        }
        return product;
      });
        this.setState({products:newProducts});
      //  console.log(this.state.products);
      };
      render() {

        return (
          <div>

            <ProductTable onProductTableUpdate={this.handleProductTable.bind(this)} onRowAdd={this.handleAddEvent.bind(this)} onRowDel={this.handleRowDel.bind(this)} products={this.state.products} filterText={this.state.filterText}/>
            <Email />
            <Phone />
          </div>
        );

      }

    }


    class ProductTable extends React.Component {

    handleSubmit(event) {
    event.preventDefault();
    //myFunction();
    console.log('In Handle submit function');
    console.log('Addresses[0]:after get', this.props.products[0].Field1);
    console.log('Addresses[0]:after get', this.props.products[0].Field2);
    console.log('Addresses[0]:after get', this.props.products[0].Field3);
    console.log('Addresses[0]:after get', this.props.products[0].Field4);
    const form = event.target;
    const data = new FormData(form);
    const arrayValue = [];
    var i = 0;
    console.log('Data from Form:', data);
    for (let name of data.keys()) {
      const input = form.elements[name];
      const parsedValue = data.get(name);
      console.log('name', name);
      console.log('parsedValue', parsedValue);
      if (typeof (parsedValue) == 'undefined' || parsedValue == null) {
        console.log('Not Defined or Not Null')
        arrayValue[i] = "";
        data.set(name, "");
      }
      else {
        data.set(name, parsedValue);
        arrayValue[i] = parsedValue;
      }
      i = i + 1;
    }

    console.log('arrayValue[4]:after get', arrayValue[4]);
    console.log('arrayValue[1]:after get', arrayValue[1]);
    console.log('arrayValue[3]:after get', arrayValue[3]);
    //console.log('Addresses[0]:after get', this.props.products[0]);

  }

      render() {
        var onProductTableUpdate = this.props.onProductTableUpdate;
        var rowDel = this.props.onRowDel;
        var filterText = this.props.filterText;
        var product = this.props.products.map(function(product) {
          if (product.Address_Line.indexOf(filterText) === -1) {
            return;
          }
          return (<ProductRow onProductTableUpdate={onProductTableUpdate} product={product} onDelEvent={rowDel.bind(this)} key={product.id}/>)
        });
        return (

          <div id="test">
                <div className="row">
                  <div className="col-lg-12">
                    <PageHeader>Test App</PageHeader>
                  </div>
                </div>
                <form onSubmit={this.handleSubmit}>
                  <table>
                    <tr>
                    <td>
                        <FormGroup style={spacing}>
                          <ControlLabel>ID</ControlLabel>
                          <FormControl
                            id="field1" name="field1"
                            type="text"
                            placeholder="Enter Text"
                          />
                        </FormGroup>
                      </td>
                      </tr>
                      <tr>
                      <td>
                      <FormGroup style={spacing}>
                          <ControlLabel> Month</ControlLabel>
                          <FormControl componentClass="select" id="MM" name="MM" placeholder="select">
                            <option value="01">01</option>
                            <option value="02">02</option>
                            <option value="03">03</option>
                            <option value="04">04</option>
                            <option value="05">05</option>
                            <option value="06">06</option>
                            <option value="07">07</option>
                            <option value="08">08</option>
                            <option value="09">09</option>
                            <option value="10">10</option>
                            <option value="11">11</option>
                            <option value="12">12</option>
                          </FormControl>
                        </FormGroup>
                      </td>
                      <td>
                      <FormGroup style={spacing}>
                          <ControlLabel> Day</ControlLabel>
                          <FormControl componentClass="select" id="DD" name="DD" placeholder="select">
                            <option value="01">01</option>
                            <option value="02">02</option>
                            <option value="03">03</option>
                            <option value="04">04</option>
                            <option value="05">05</option>
                            <option value="06">06</option>
                            <option value="07">07</option>
                            <option value="08">08</option>
                            <option value="09">09</option>
                            <option value="10">10</option>
                            <option value="11">11</option>
                            <option value="12">12</option>
                            <option value="13">13</option>
                            <option value="14">14</option>
                            <option value="15">15</option>
                            <option value="16">16</option>
                            <option value="17">17</option>
                            <option value="18">18</option>
                            <option value="19">19</option>
                            <option value="20">20</option>
                            <option value="21">21</option>
                            <option value="22">22</option>
                            <option value="23">23</option>
                            <option value="24">24</option>
                            <option value="25">25</option>
                            <option value="26">26</option>
                            <option value="27">27</option>
                            <option value="28">28</option>
                            <option value="29">29</option>
                            <option value="30">30</option>
                            <option value="31">31</option>
                          </FormControl>
                        </FormGroup>
                      </td>
                  </table>
                  </form>
          <div className="col-lg-15">
          <th>Address</th>
          <button type="button" onClick={this.props.onRowAdd} className="btn btn-success pull-right">+</button>
            <table className="table table-bordered">
              <thead>
                <tr>
                  <th>Field1</th>
                  <th>Field2</th>
                  <th>Field3</th>
                  <th>field4</th>
                  <th>field5</th>
                  <th>field6</th>
                  <th>field7</th>
                </tr>
              </thead>

              <tbody>
                {product}

              </tbody>

            </table>
          </div>
          </div>
        );

      }

    }

    class ProductRow extends React.Component {
      onDelEvent() {
        this.props.onDelEvent(this.props.product);

      }
      render() {

        return (
          <tr className="eachRow">
            <EditableCell onProductTableUpdate={this.props.onProductTableUpdate} cellData={{
              "type": "Field1",
              value: this.props.product.Field1,
              id: this.props.product.id
            }}/>
            <EditableCell onProductTableUpdate={this.props.onProductTableUpdate} cellData={{
              type: "Field2",
              value: this.props.product.Field2,
              id: this.props.product.id
            }}/>
            <EditableCell onProductTableUpdate={this.props.onProductTableUpdate} cellData={{
              type: "Field3",
              value: this.props.product.Field3,
              id: this.props.product.id
            }}/>
            <EditableCell onProductTableUpdate={this.props.onProductTableUpdate} cellData={{
              type: "Field4",
              value: this.props.product.Field4,
              id: this.props.product.id
            }}/>
             <EditableCell onProductTableUpdate={this.props.onProductTableUpdate} cellData={{
              type: "Field5",
              value: this.props.product.Field5,
              id: this.props.product.id
            }}/>
            <EditableCell onProductTableUpdate={this.props.onProductTableUpdate} cellData={{
              type: "Field6",
              value: this.props.product.Field6,
              id: this.props.product.id
            }}/>
            <EditableCell onProductTableUpdate={this.props.onProductTableUpdate} cellData={{
              type: "Field7",
              value: this.props.product.Field7,
              id: this.props.product.id
            }}/>
            <td className="del-cell">
              <input type="button" onClick={this.onDelEvent.bind(this)} value="REMOVE" className="del-btn"/>
            </td>
          </tr>
        );

      }

    }
    class EditableCell extends React.Component {

      render() {
        return (
          <td>
            <input type='text' name={this.props.cellData.type} id={this.props.cellData.id} value={this.props.cellData.value} onChange={this.props.onProductTableUpdate}/>
          </td>
        );

      }

    }


    displayForms.contextTypes = { setTitle: PropTypes.func.isRequired };

    export default displayForms;

//import React, { PropTypes , Component } from 'react';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
  Panel,
  Button,
  Col,
  PageHeader,
  ControlLabel,
  FormControl,
  HelpBlock,
  FormGroup,
  Checkbox,
  Form,
  Radio,
  InputGroup,
  Glyphicon } from 'react-bootstrap';

import FormControlFeedback from 'react-bootstrap/lib/FormControlFeedback';
import FormControlStatic from 'react-bootstrap/lib/FormControlStatic';
import InputGroupAddon from 'react-bootstrap/lib/InputGroupAddon';





class Phone extends React.Component {

  constructor(props) {
    super(props);

    //  this.state.phones = [];
    this.state = {};
    this.state.filterText = "";
    this.state.phones = [
      {
        id: 1,
       Field1: '',
       Field2: '',
       Field3: '',
       Field4: '',
       Field5: ''
      }
    ];

  }
  handleUserInput(filterText) {
    this.setState({filterText: filterText});
  };
  handleRowDel(phone) {
    var index = this.state.phones.indexOf(phone);
    this.state.phones.splice(index, 1);
    this.setState(this.state.phones);
  };

  handleAddEvent(evt) {
    var id = (+ new Date() + Math.floor(Math.random() * 999999)).toString(36);
    var phone = {
      id: id,
      Phone_Number: '',
       Type: '',
       Receive_Calls: '',
       Receive_Texts: '',
       Preferred_Phone_Number: ''

    }
    this.state.phones.push(phone);
    this.setState(this.state.phones);

  }

  handlephoneTable(evt) {
    var item = {
      id: evt.target.id,
      name: evt.target.name,
      value: evt.target.value
    };
    console.log('item.value in phone',item.value);
var phones = this.state.phones.slice();
  var newphones = phones.map(function(phone) {

    for (var key in phone) {
      if (key == item.name && phone.id == item.id) {
        phone[key] = item.value;

      }
    }
    return phone;
  });
    this.setState({phones:newphones});
  //  console.log(this.state.phones);
  };
  render() {

    return (
      <div>

        <PhoneTable onphoneTableUpdate={this.handlephoneTable.bind(this)} onRowAdd={this.handleAddEvent.bind(this)} onRowDel={this.handleRowDel.bind(this)} phones={this.state.phones} filterText={this.state.filterText}/>
      </div>
    );

  }

}


class PhoneTable extends React.Component {

  render() {
    var onphoneTableUpdate = this.props.onphoneTableUpdate;
    var rowDel = this.props.onRowDel;
    var filterText = this.props.filterText;
    var phone = this.props.phones.map(function(phone) {
      if (phone.Type.indexOf(filterText) === -1) {
        return;
      }
      return (<PhoneRow onphoneTableUpdate={onphoneTableUpdate} phone={phone} onDelEvent={rowDel.bind(this)} key={phone.id}/>)
    });
    return (
      <div>

    <th>Phone</th>
      <button type="button" onClick={this.props.onRowAdd} className="btn btn-success pull-right">Add</button>
        <table className="table table-bordered">
          <thead>
            <tr>
              <th>Phone_Number</th>
              <th>Type</th>
              <th>Receive_Calls</th>
              <th>Receive_Texts</th>
              <th>Preferred_Phone_Number</th>
            </tr>
          </thead>

          <tbody>
            {phone}

          </tbody>

        </table>
      </div>
    );

  }

}

class PhoneRow extends React.Component {
  onDelEvent() {
    this.props.onDelEvent(this.props.phone);

  }
  render() {

    return (
      <tr className="eachRow">
        <EditableCell onphoneTableUpdate={this.props.onphoneTableUpdate} cellData={{
          "type": "Field1",
          value: this.props.phone.Field1,
          id: this.props.phone.id
        }}/>
        <EditableCell onphoneTableUpdate={this.props.onphoneTableUpdate} cellData={{
          type: "Field2",
          value: this.props.phone.Field2,
          id: this.props.phone.id
        }}/>
        <EditableCell onphoneTableUpdate={this.props.onphoneTableUpdate} cellData={{
          type: "Field3",
          value: this.props.phone.Field3,
          id: this.props.phone.id
        }}/>
        <EditableCell onphoneTableUpdate={this.props.onphoneTableUpdate} cellData={{
          type: "Field4",
          value: this.props.phone.Field4,
          id: this.props.phone.id
        }}/>
        <EditableCell onphoneTableUpdate={this.props.onphoneTableUpdate} cellData={{
          type: "Field5",
          value: this.props.phone.Field5,
          id: this.props.phone.id
        }}/>
        <td className="del-cell">
          <input type="button" onClick={this.onDelEvent.bind(this)} value="REMOVE" className="del-btn"/>
        </td>
      </tr>
    );

  }

}
class EditableCell extends React.Component {

  render() {
    return (
      <td>
        <input type='text' name={this.props.cellData.type} id={this.props.cellData.id} value={this.props.cellData.value} onChange={this.props.onphoneTableUpdate}/>
      </td>
    );

  }

}


export default Phone;

1 个答案:

答案 0 :(得分:1)

您可以将回调从父组件传递到子组件,以便子组件可以更新父组件中的状态。这是演示此示例代码:

class Parent extends React.Component {
  constructor(props) {
    super(props);
      this.state = {
        phone: ''
      }
    this.phoneChange = this.phoneChange.bind(this);
  }
  
  componentDidUpdate() {
    console.log('Parent state:', this.state.phone);
  }

  phoneChange(phone) {
    console.log('child value', phone)
    this.setState({phone});
  }

  render() {
    return (
    <div>
      Phone:
      <Child
      phoneChange = {
        this.phoneChange
      }
      />
    </div>)
  }
}

class Child extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        phone: ''
      }
      this.handleChange = this.handleChange.bind(this);
    }

    handleChange(e) {
      const phone = e.target.value;
      this.setState({
        phone
      })
      this.props.phoneChange(phone);
    }

    render() {
      return ( < input value = {
          this.state.phone
        }
        onChange = {
          this.handleChange
        }
      />);
   }
}

ReactDOM.render( < Parent / > ,
  document.getElementById('root')
);
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>

<div id="root" />

相关问题