Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从多个子组件更新父组件状态';componentDidMount()同步安装_Javascript_Reactjs_Lifecycle_Children_Direction - Fatal编程技术网

Javascript 从多个子组件更新父组件状态';componentDidMount()同步安装

Javascript 从多个子组件更新父组件状态';componentDidMount()同步安装,javascript,reactjs,lifecycle,children,direction,Javascript,Reactjs,Lifecycle,Children,Direction,好的,这个问题有点棘手。我一直在思考这是否是正确的概念,考虑到React应该是一个单向的数据流,从父母到孩子,而不是相反。但我还是想把这个问题贴出来,这样我会得到不同的意见,甚至有可能找到一种方法让它发挥作用 在我的应用程序中,我有一个相当大的组件,它接受表单作为它的子元素,并且做了一些巧妙的反应,将其方法传递给子元素,因此当子元素发生更改时,它们会触发父组件方法,这些方法将数据存储在状态中并处理表单提交。它工作得非常好,但是它不太擅长捕捉“defaultvalue” 简而言之,我试图在chil

好的,这个问题有点棘手。我一直在思考这是否是正确的概念,考虑到React应该是一个单向的数据流,从父母到孩子,而不是相反。但我还是想把这个问题贴出来,这样我会得到不同的意见,甚至有可能找到一种方法让它发挥作用

在我的应用程序中,我有一个相当大的组件,它接受表单作为它的子元素,并且做了一些巧妙的反应,将其方法传递给子元素,因此当子元素发生更改时,它们会触发父组件方法,这些方法将数据存储在状态中并处理表单提交。它工作得非常好,但是它不太擅长捕捉“defaultvalue”

简而言之,我试图在chilren的ComponentMount()方法上触发我的父方法,它是有效的,但是,如果有多个子方法尝试这样做,则该方法会被调用两次,但它只使用第二个子数据集

我用以下代码创建了我的问题的简化版本:

import React from 'react'

export class Parent extends React.Component {
    constructor(props){
        super(props)
        this.state = {
            data : {name:'james'}
        }
        this.updateData = this.updateData.bind(this)
    }

    updateData(key,data){
        console.log('updating data')
        this.setState({
            data : {...this.state.data,[key]:data}
        })
    }

    render(){
        console.log(this.state)
        return (
            <div>
                <Child1 updateData={this.updateData}/>
                <Child2 updateData={this.updateData}/> 
            </div>
        )
    }
}

class Child1 extends React.Component {

    componentDidMount(){
        this.props.updateData('child1','myData')
    }

    render(){
        return (
            <div>
                I am Child 1
            </div>
        )
    }
}

class Child2 extends React.Component {

    componentDidMount(){
        this.props.updateData('child2','myData2')
    }

    render(){
        return (
            <div>
                I am Child 2
            </div>
        )
    }
}
从“React”导入React
导出类父类扩展React.Component{
建造师(道具){
超级(道具)
此.state={
数据:{name:'james'}
}
this.updateData=this.updateData.bind(this)
}
更新数据(键、数据){
console.log('更新数据')
这是我的国家({
数据:{…this.state.data[key]:data}
})
}
render(){
console.log(this.state)
返回(
)
}
}
类Child1扩展了React.Component{
componentDidMount(){
this.props.updateData('child1','myData')
}
render(){
返回(
我是一个孩子
)
}
}
类Child2扩展了React.Component{
componentDidMount(){
this.props.updateData('child2','myData2')
}
render(){
返回(
我是孩子2
)
}
}
此代码将在控制台上呈现两次“更新数据”,但它将仅使用child2中发送的数据更新状态。同样,考虑到im从其子组件设置父组件的状态,我可以看出这可能不是最好的方法,但对于在不同子组件上多次重用的父组件上设置默认值,这将是一个很好的解决方案


Im all ears stack overflow

我认为问题在于
setState
同时执行两个更新(对它们进行批处理),这意味着在合并两个部分状态时使用相同的初始状态。您需要使用updater函数,如kind user所示:


开始时最好在
setState
函数中使用callback
this.setState((prevState)=>({data:{…prevState.data,[key]:data}))this.setState((prevState) => ({ data: { ...prevState.data, [key]: data } }));