React-如何从子组件获取状态数据?

时间:2020-01-29 13:51:56

标签: javascript reactjs forms

我刚刚开始学习反应,并且我正在构建一个表单,到目前为止,我已经创建了父组件“ Form”,并且将其余输入作为组件进行了分离,每个组件都有自己的状态。 。我的问题是提交表单时如何从子组件中获取状态数据并在父组件“表单”中使用它?

这是我的父组件

import React, { Component } from "react";

import Name from "components/Name";
import Email from "components/Email";
import Select from "components/Select";
import Bio from "components/Bio";

class Form extends Component {
    handleSubmit = event => {
        event.preventDefault();
    };

    render() {
        return (
            <form onSubmit={this.handleSubmit}>
                <div className="shape rectangle"></div>
                <div className="shape triangle"></div>
                <div className="shape circle"></div>
                <Name />
                <Email />
                <Select />
                <Bio />
                <button type="submit" className="btn">
                    Submit
                </button>
            </form>
        );
    }
}

export default Form;

子组件之一

import React, { Component } from "react";

// Create Name component for name && email inputs
class Name extends Component {
  constructor(props) {
    super(props);

    this.state = {
      firstName: "",
      lastName: ""
    };
  }

  // Handle first name input on change event
  handleFirstNameChange = event => {
    this.setState({
      firstName: event.target.value
    });
  };

  // Handle last name input on change event
  handleLastNameChange = event => {
    this.setState({
      lastName: event.target.value
    });
  };

  // Render labels and name inputs
  render() {
    const { firstName, lastName } = this.state;
    return (
      <div className="form-names">
        <label htmlFor="firstName">Name</label>
        <br/>
        <input
          type="text"
          name="firstName"
          value={firstName}
          placeholder="First Name"
          id="firstName"
          onChange={this.handleFirstNameChange}
        />
        <input
          type="text"
          name="lastName"
          value={lastName}
          placeholder="Last Name"
          id="lastName"
          onChange={this.handleLastNameChange}
        />
      </div>
    );
  }
}

export default Name;

4 个答案:

答案 0 :(得分:1)

要完成此操作,您需要将“状态提升”到一个公共的父组件(称为祖先组件),在您的情况下,这将是<Form>组件。然后,您可以将值作为props传递给每个相应的子组件。

它看起来像这样:

import React, { Component } from "react";

import Name from "./Name";
// More imports go here..

class Form extends Component {
  state = {
    firstName: "",
    lastName: ""
  };

  handleSubmit = event => {
    event.preventDefault();
  };

  // Handle first name input on change event
  handleFirstNameChange = event => {
    this.setState({
      firstName: event.target.value
    });
  };

  // Handle last name input on change event
  handleLastNameChange = event => {
    this.setState({
      lastName: event.target.value
    });
  };

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <Name
          firstName={this.state.firstname}
          lastName={this.state.lastName}
          handleFirstNameChange={this.handleFirstNameChange}
          handleLastNameChange={this.handleLastNameChange}
        />
        {/* More components go here.. */}
        <p>Current state:</p>
        {JSON.stringify(this.state)}
      </form>
    );
  }
}

export default Form;

Working example

更多信息:Lifting state up来自官方的React文档。

答案 1 :(得分:0)

您可以使用ContextRedux之类的东西,这将允许您创建通用存储并从任何组件中检索状态 或在父组件中创建方法,将它们传递给它的子代,然后从该子代组件中调用它们。例如,您可能在handleFirstNameChange中有Form并将其向下传递到Name。这样一来,您现在就可以将name之类的道具也保留在Form中,并将其传递下去。

答案 2 :(得分:0)

您可以在父组件中使用单个状态,并在道具中传递名字和姓氏,您的代码将变为:

import React, { Component } from "react";

import Name from "components/Name";
import Email from "components/Email";
import Select from "components/Select";
import Bio from "components/Bio";

class Form extends Component {
  state = {
    firstName: '',
    lastName: '',
  }

  onChange = (e) => {
  this.setState({[e.target.name] : e.target.value})
  }

  handleSubmit = event => {
   event.preventDefault()
  }

  render() {
    return (
        ...
        <Name onChange={this.onChange} firstName={this.state.firstName} lastName={this.state.lastName} />
        ...
        <button type="submit" className="btn">
          Submit
        </button>
       </form>
    )
  }
}

export default Form;

并且您的子组件变为:

import React, { Component } from "react";

// Create Name component for name && email inputs
class Name extends Component {


  render() {
    const { firstName, lastName , onChange} = this.props;
    return (
      <div className="form-names">
        <label htmlFor="firstName">Name</label>
        <br/>
        <input
          type="text"
          name="firstName"
          value={firstName}
          placeholder="First Name"
          id="firstName"
          onChange={onChange}
        />
        <input
          type="text"
          name="lastName"
          value={lastName}
          placeholder="Last Name"
          id="lastName"
          onChange={onChange}
        />
      </div>
    );
  }
}

export default Name;

答案 3 :(得分:0)

我的想法是执行以下操作,将数据作为道具传递给组件。但这对我来说没有意义,因为当您单击提交按钮时,该表单会从父组件中收集数据。最好将表单保留在父组件中,并将所有输入数据分组为状态。

import React, { Component } from "react";

import Name from "components/Name";
import Email from "components/Email";
import Select from "components/Select";
import Bio from "components/Bio";

class Form extends Component {
    constructor(props){
      super(props)
      this.state = {
        firstName = "",
        lastName = "",
        (and other input data you need)...
      }
    }

    handleSubmit = event => {
        event.preventDefault();
    };

    render() {
        return (
            <form onSubmit={this.handleSubmit}>
                <div className="shape rectangle"></div>
                <div className="shape triangle"></div>
                <div className="shape circle"></div>
                <Name firstName={this.state.firstName} lastName={this.state.lastName}/>
                <Email (inputData as props)/>
                <Select (inputData as props)/>
                <Bio (inputData as props)/>
                <button type="submit" className="btn">
                    Submit
                </button>
            </form>
        );
    }
}

export default Form;