React子组件状态更新父组件状态

时间:2017-10-03 06:13:25

标签: reactjs

为什么子状态数据更改会更新父状态数据?

我想在子表单完成后才更新父数据。

export default class StepOne extends React.Component{
    constructor(props){
        super(props)
        this.state = {
            data: this.props.data
        }
        this.handleChanges = this.handleChanges.bind(this);
    }
    handleChanges(e){
        var data = this.state.data
        console.log(this.props.data) //{loan_amount: "", validate: false}
        var name = e.target.name
        var value = e.target.value
        data[name] = e.target.value
        this.setState({data})
        console.log(this.props.data) //{loan_amount: "1", validate: false}
    }
    render() {
        return (
            <div>
                <h4 className="form-ques">Loan Details</h4>
                <Row>
                    <Input label="Required Amount" type="number" name="loan_amount" onChange={this.handleChanges} value={this.state.data.loan_amount}/>
                </Row>
            </div>
    )}
}

3 个答案:

答案 0 :(得分:1)

根据您的问题,您的父组件或子组件是什么并不明显。如果此代码表示您的子组件,则需要将 handleChanges(e)移动到父组件,因为现在您正在设置子状态而不是父状态。

答案 1 :(得分:1)

您的父状态根据孩子发生变化的原因是您正在改变状态,从而直接改变道具

constructor(props){
    super(props)
    this.state = {
        data: this.props.data .  // <-- props are assigned to state by reference here
    }
    this.handleChanges = this.handleChanges.bind(this);
}
handleChanges(e){
    var data = this.state.data .  // <-- the state data and thus the prop data are assigned to data by reference here
    console.log(this.props.data) //{loan_amount: "", validate: false}
    var name = e.target.name
    var value = e.target.value
    data[name] = e.target.value // <-- since data references state and prop directly you are modifying them both by modifying data.
    this.setState({data})
    console.log(this.props.data) //{loan_amount: "1", validate: false}
}

解决方案很简单,您需要克隆对象状态数据,而不是使用spread syntax

直接分配它
handleChanges(e){
    var data = {...this.state.data} //Spread syntax creates a new object for you 
    console.log(this.props.data) 
    var name = e.target.name
    var value = e.target.value
    data[name] = e.target.value
    this.setState({data})
    console.log(this.props.data) 
}

答案 2 :(得分:0)

而不是像这样做你可以做这样的事情

export default class StepOne extends React.Component{
constructor(props){
   super(props)
   // You don't need the state here
   //this.state = {
   // data: this.props.data
   //}
   this.handleChanges = this.handleChanges.bind(this);
}

// you don't need this here as well
handleChanges(e){
   //var data = this.state.data
   //console.log(this.props.data) //{loan_amount: "", validate: false}
   //var name = e.target.name
   //var value = e.target.value
   //data[name] = e.target.value
   //this.setState({data})
   //console.log(this.props.data) //{loan_amount: "1", validate: false}
}

render() {
    const { loan_amount, validate } = this.props.data;
    return (
      <div>
        <h4 className="form-ques">Loan Details</h4>
        <Row>
          <Input 
           label="Required Amount" 
           type="number" 
           name="loan_amount" 
           onChange={this.props.onHandleChange} //New method to change value 
           value={loan_amount} // Getting this value from props
          />
       </Row>
     </div>
)}

然后在您已定义所有内容的父类中创建一个名为。

的函数
onHandleChange = (e) => {
   var data = this.state.data;
   data[e.target.name] = e.target.value;
   this.setState({ data });
}

这样,每次更改子组件时,只有一个data字段在父组件中发生更改,而您的父组件是更新/更改表单的字段。

我希望如果您还有任何问题,请告诉我。