从多个子组件的componentDidMount()同步更新父组件状态

时间:2018-12-04 22:30:45

标签: javascript reactjs lifecycle children direction

好的,这个问题有点棘手。我一直在考虑这是否是正确的概念,考虑到React应该是单向数据流,从父级到子级,而不是相反。但是我还是想发布这个问题,这样我才能获得不同的意见,甚至可能是使它生效的一种方法。

在我的应用程序中,我有一个相当大的组件,它接受表单作为其子级,并执行一些漂亮的React魔术将其方法传递给子级,因此当子级元素发生更改时,它们会触发存储该元素的父级组件方法。处于状态的数据并处理表单提交。它工作得很好,但是在捕获“ defaultValues”方面并不是那么好。

简而言之,我试图在孩子的componentidMount()方法上触发我的父方法,并且它可以工作,但是,如果有多个孩子尝试这样做,则该方法被调用两次,但仅使用第二个孩子的数据集。

我已通过以下代码创建了该问题的简化版本:

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

此代码将在控制台上两次渲染“更新数据”,但只会使用child2中发送的数据来更新状态。再次,我可以看到这可能不是最好的方法,考虑到从子对象设置父对象的状态,但是这对于在父组件上设置默认值是一个很好的解决方案,该组件在不同子对象之间可以重复使用。

我所有的耳朵都堆满了

1 个答案:

答案 0 :(得分:1)

我认为问题在于setState同时执行两个更新(批处理),这意味着合并两个部分状态时会使用相同的初始状态。您需要使用种类用户所示的更新程序功能:

this.setState((prevState) => ({ data: { ...prevState.data, [key]: data } }));