如何处理从父组件到子组件的道具以在表单中填充道具数据以进行更新

How to handle the props from Parent Component to child component to populate props data in the form for updation

我想编辑我的应用程序的访客数据。为什么我点击编辑按钮我获取 ID,将其发送到 GUEST class component 然后我从 state 获取数据然后我将它发送到 输入组件 (GuestForm)。问题是我能够在 GuestForm 组件 中获取编辑数据,但我想以某种方式设置状态...这样我就可以在表单中看到要编辑的数据人口稠密。请帮助我,我是 React 的新手。我尝试搜索不同的生命周期方法,但找不到。在此之后,我将使用 componentDidUpdate() 来处理更新数据。 但请帮我将数据从 props 填充到表单

我正在使用 Class 组件。所以请仅在这方面帮助我。

这是我的代码index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Guest Register</title>
    <!--BOOTSTRAP, FONTAWESOME CDN-->
    <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
      integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
      crossorigin="anonymous"
    />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.css"
      integrity="sha256-46qynGAkLSFpVbEBog43gvNhfrOj+BmwXdxFgVK/Kvc="
      crossorigin="anonymous"
    />
    <!--END-->
  </head>
  <body class="bg-white">
    <!--ROOT ELEMENT-->
    <div id="root"></div>
    <!--END OF ROOT ELEMENT-->

    <!--REACT,REACT-DOM, BABEL CONFIG CDN-->
    <script
      crossorigin
      src="https://unpkg.com/react@16/umd/react.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <!--END OF CONFIG CDN-->

    <!--APPLICATION MAIN CODE-->
    <script src="App.js" type="text/babel"></script>
    <!--APPLICATION CODE END-->
  </body>
</html>

这是我的App.js

class GuestForm extends React.Component {
  state = {
    name: "",
    guestType: "",
    isEdit: false
  };

  changeName(name) {
    this.setState({
      name: name
    });
  }

  changeGuestType(type) {
    this.setState({
      guestType: type
    });
  }

  submitForm() {
    this.props.getGuestData(this.state);
    this.setState({
      name: "",
      guestType: ""
    });
  }

  componentDidUpdate = (prevProp, newProp) => {
    console.log("CDU: ", prevProp, newProp);
  };

  render() {
    return (
      <form>
        <div className="form-group">
          <input
            type="text"
            className="form-control"
            placeholder="Guest Name"
            value={
              this.props.dataToEdit.name
                ? this.props.dataToEdit.name
                : this.state.name
            } //value attribute doesn't works here
            onChange={event => this.changeName(event.target.value)}
            required
          />
        </div>
        <div className="form-group">
          <select
            className="form-control"
            value={
              this.props.dataToEdit.guestType
                ? this.props.dataToEdit.guestType
                : this.state.guestType
            }
            onChange={event => this.changeGuestType(event.target.value)}
            required
          >
            <option value="">Choose Type</option>
            <option value="VIP">VIP</option>
            <option value="NORMAL">Normal</option>
            <option value="CHIEF GUEST">Chief Guest</option>
          </select>
        </div>
        <button
          onClick={e => {
            e.preventDefault();
            this.submitForm();
          }}
          className="btn btn-primary"
        >
          {this.props.dataToEdit.isEdit ? "UPDATE" : "ADD"}
        </button>
      </form>
    );
  }
}

class GuestList extends React.Component {
  guestToDelete(id) {
    this.props.getTheIdToDelete(id);
  }
  guestToEdit(id) {
    this.props.getTheIdToEdit(id);
  }
  render() {
    return (
      <tr key={this.props.index}>
        <td scope="row">{this.props.name}</td>
        <td>{this.props.guestType}</td>
        <td>
          <a onClick={() => this.guestToEdit(this.props.index)}>
            <i className="far fa-edit text-info"></i>
          </a>
          &nbsp;&nbsp;
          <a onClick={() => this.guestToDelete(this.props.index)}>
            <i className="fa fa-trash-alt text-danger"></i>
          </a>
        </td>
      </tr>
    );
  }
}

class Guest extends React.Component {
  state = {
    guests: [],
    editGuestdata: []
  };

  getFormDataForGuests(data) {
    if (data.name && data.guestType) {
      this.setState(
        {
          guests: [...this.state.guests, data]
        },
        () => {
          console.log("GUEST:", this.state);
        }
      );
    }
  }

  guestToDelete(id) {
    let updatedGuest = [...this.state.guests];
    updatedGuest.splice(id, 1);
    this.setState({
      guests: updatedGuest
    });
  }

  guestToEdit(id) {
    let editData = {
      name: this.state.guests[id].name,
      guestType: this.state.guests[id].guestType,
      isEdit: true
    };
    this.setState({
      editGuestdata: editData
    });
  }

  render() {
    return (
      <div className="row text-center m-2">
        <div className="col-md-5 card mx-auto shadow m-1 p-3 col-xs-10">
          <h3>Guest Form</h3>
          <GuestForm
            dataToEdit={this.state.editGuestdata}
            getGuestData={data => this.getFormDataForGuests(data)}
          />
        </div>
        <div className="col-md-5 card mx-auto m-1 p-3 shadow col-xs-10">
          <table className="table table-striped">
            <thead>
              <tr>
                <th>Name</th>
                <th>Guest Type</th>
                <th>Edit/Delete</th>
              </tr>
            </thead>
            <tbody>
              {this.state.guests.map((data, index) => {
                return (
                  <GuestList
                    getTheIdToDelete={id => this.guestToDelete(id)}
                    getTheIdToEdit={id => this.guestToEdit(id)}
                    index={index}
                    name={data.name}
                    guestType={data.guestType}
                  />
                );
              })}
            </tbody>
          </table>
        </div>
      </div>
    );
  }
}

ReactDOM.render(<Guest />, document.getElementById("root"));

尝试访问表单组件中 'dataToEdit' 的值。

<input
   type="text"
   className="form-control"
   placeholder="Guest Name"
   value={this.props.dataToEdit.name} //this will pull in as props not state
   onChange={event => this.changeName(event.target.value)}
   required
/>

如果仍然无法正常工作,则 dataToEdit 设置不正确。

在 GuestForm 中更改您的状态对象,如下所示

它将根据道具初始化您的应用初始状态。

 state = {
    name: this.props.name,
    guestType: this.props.guestType,
    isEdit: false
  };

您也可以使用构造函数对其进行初始化。

constructor (props){
super(props)
this.state = {
        name: props.name,
        guestType: props.guestType,
        isEdit: false
      };
}

您可以尝试 gerDerivedStateFromProps 生命周期方法使用来自父级的 props 来初始化状态。

 state = {
           name: '',
           guestType: '',
           isEdit: false
       };

static getDerivedStateFromProps(nextProps, prevState) {

  return {
    name: nextProps.name,
    guestType: nextProps.guestType,
    isEdit: false
  };
}

在此之后,您可以使用常规方法更新状态,例如 setState() 并更新值。