如何在React.JS中将状态从子组件传递给父组件?

时间:2019-06-09 16:33:21

标签: javascript reactjs

我有一个包含10多个输入字段的表单,用于更新类的状态。为了使内容看起来更整洁,我将带有标签的所有输入字段移到了单独的组件中,以便可以将其重新用于每个输入。该组件有两个参数,在我的主类中用作子代。

子组件:

    const Input = ({ name, placeholder }) => {
      return (
        <div className="wrapper">
          <Row className="at_centre">
            <Col sm="2" style={{ marginTop: "0.5%" }}><Form.Label>{ name }</Form.Label></Col>
            <Col sm="5"><Form.Control placeholder={ placeholder }/></Col>
          </Row>
        </div>
      )
    }

父母:

    state = { name: '', description: '' }

    handleSubmit = (e) => {
        e.preventDefault()
        console.log(this.state);
    }

    render(){
        return(
            <Form style={{ marginBottom: "5%", padding: 10 }} onSubmit={ this.handleSubmit } >
                <Input name="Name: " placeholder="How is it called?" onChange={ (event) => this.setState({name: event.target.value}) }/>
                <Input name="Description: " placeholder="Please describe how does it look like?" onChange={ (event) => this.setState({description: event.target.value}) }/>

                <Button variant="outline-success" size="lg" type="submit" >SUBMIT</Button>
            </Form>            
        )
    }

这样做之后,我找不到在更改文本时如何从子组件更新状态的方法。我所做的所有尝试都使网站崩溃或什么也没做。我仍然是React.js的新手,因此感谢您的反馈。

3 个答案:

答案 0 :(得分:0)

onChange事件传递给您的子组件,并使用Form.Control控件进行连接。

您的Input组件将是

const Input = ({ name, placeholder, onChange }) => {
  return (
    <div className="wrapper">
      <Row className="at_centre">
        <Col sm="2" style={{ marginTop: "0.5%" }}>
          <Form.Label>{name}</Form.Label>
        </Col>
        <Col sm="5">
          <Form.Control onChange={onChange} placeholder={placeholder} />
        </Col>
      </Row>
    </div>
  );
};

您的Parent组件是

class Parent extends React.Component {
  state = { name: "", description: "" };

  handleSubmit = e => {
    e.preventDefault();
    console.log(this.state);
  };

  render() {
    return (
      <Form
        style={{ marginBottom: "5%", padding: 10 }}
        onSubmit={this.handleSubmit}
      >
        <Input
          name="Name: "
          placeholder="How is it called?"
          onChange={event => this.setState({ name: event.target.value })}
        />
        <Input
          name="Description: "
          placeholder="Please describe how does it look like?"
          onChange={event => this.setState({ description: event.target.value })}
        />

        <Button variant="outline-success" size="lg" type="submit">
          SUBMIT
        </Button>
      </Form>
    );
  }
}

工作代码沙盒here

答案 1 :(得分:0)

在React中,属性从父组件流到子组件,因此您不能直接将状态从子组件“传递”给父组件。

但是,您可以做的是让父级将回调函数传递给子级,该子级将被调用以更新父级的状态。

这里是一个例子:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: '',
    };
  }

  updateName(name) {
    if (name === this.state.name) return;
    this.setState({ name });
  }

  render() {
    return (
      <div>
        <p>The name is {this.state.name}</p>
        <ChildComponent handleNameUpdate={name => this.updateName(name)} />
      </div>
    );
  }
}

class ChildComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: '',
    };
  }

  handleInputChange(e) {
    this.setState({ name: e.target.value });
    this.props.handleNameUpdate(e.target.value)
  }

  render() {
    return <input type="text" value={this.state.name} onChange={e => this.handleInputChange(e)} />;
  }
}

答案 2 :(得分:0)

您必须构建所谓的受控组件。

const Input = ({ label, name, onChange, placeholder }) => (
        <div className="wrapper">
          <Row className="at_centre">
            <Col sm="2" style={{ marginTop: "0.5%" }}>
              <Form.Label>{ label }</Form.Label></Col>
            <Col sm="5">
              <Form.Control name={ name }
                            value={ value } 
                            placeholder={ placeholder }
                            onChange={ onChange }
               />
            </Col>
          </Row>
        </div>
      )

在您的父母中

state = { name: '', description: '' }

handleChange = ({ target: { name, value } }) => this.setState({ [name]: value })

render() {
 const { name, description } = this.state
  <Form style={{ marginBottom: "5%", padding: 10 }} onSubmit={ this.handleSubmit } >
    <Input label="Name: " name="name" value={name} onChange={handleChange}/>
    <Input label="Description: " description="description" value={description} onChange={handleChange}/>
    <Button variant="outline-success" size="lg" type="submit" >SUBMIT</Button>
  </Form>      
}

建议

尽量避免在render函数内部制造lambda方法,并且应将其作为lambda方法具有类属性,这样就不必在每个渲染周期都制造lambda。