【问题标题】:React child component state updates parent component stateReact 子组件状态更新父组件状态
【发布时间】:2017-10-03 06:13:25
【问题描述】:

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

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

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>
    )}
}

【问题讨论】:

    标签: reactjs


    【解决方案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】:

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

    【讨论】:

    • 很抱歉没有提到它的子状态。我只是想知道这如何更新父组件数据
    【解决方案3】:

    与其这样,你也可以这样做

    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 字段在父组件中发生更改,而父组件是更新/更改表单的那个。

    希望对您有所帮助,如果您仍有任何问题,请告诉我。

    【讨论】:

    • 你能告诉我我的代码是如何更新父状态数据的吗?
    • 在您的 handleChange 事件中,您的日志记录不正确的控制台,您不可能更改子组件中的某些内容并且不通过函数将其与父组件链接。父状态值发生变化。您需要分享整个代码,以便有人告诉您为什么会这样。
    • 这也是困扰我的问题。请参阅@Shubham Khatri 的回答。
    • 是的,看到了,:) 太好了。
    猜你喜欢
    • 2018-10-09
    • 2021-01-12
    • 2021-01-03
    • 1970-01-01
    • 2020-05-31
    • 2018-02-20
    • 2021-06-08
    • 2017-09-28
    • 1970-01-01
    相关资源
    最近更新 更多