简体   繁体   English

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

[英]Updating Parent Component state from multiple child components' componentDidMount() synchronously

Ok so this question is a bit tricky. 好的,所以这个问题有点棘手。 I have been thinking about whether this is even correct concept wise, considering React is supposed to be a one-way flow of data, from parent to children, and not viceversa. 我一直在考虑这是否是正确的概念,考虑到React应该是单向数据流,从父级到子级,而不是相反。 But I would like to post the question anyway so I get different opinions and even possibly a way to get this to work. 但是无论如何,我都想发布问题,以便获得不同的意见,甚至可能是使该问题生效的一种方法。

In my app, I have a pretty large component that accepts forms as its children, and does some nifty React magic to pass its methods to the children so when the children elements are changed, they trigger the parent components methods that store the data in state and handles the form submissions. 在我的应用程序中,我有一个相当大的组件,它接受表单作为其子级,并执行一些漂亮的React魔术将其方法传递给子级,因此当子级元素发生更改时,它们会触发以状态存储数据的父级组件方法并处理表单提交。 It works very nicely, however it is not so good at catching "defaultValues". 它工作得很好,但是在捕获“ defaultValues”方面并不是那么好。

In a nutshell, I'm trying to trigger my parent method on the chilren's componentidMount() method, and it works, however, if there's more than one child trying to do this, the method gets called twice but it only uses the second child's dataset. 简而言之,我试图在孩子的componentidMount()方法上触发我的父方法,并且它可以工作,但是,如果有多个尝试这样做的孩子,则该方法被调用两次,但仅使用第二个孩子的数据集。

I have created a simplified version of my issue in the following code: 我在以下代码中创建了我的问题的简化版本:

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

This code will render 'updating data' twice on the console, but it will only update the state with the data sent in child2. 该代码将在控制台上两次呈现“更新数据”,但只会使用child2中发送的数据来更新状态。 Again, I can see how this may not be the best approach considering that im setting the state of a parent from its children, but it would be a good solution for setting default values on a parent component that gets reused a lot with different children. 再次,我可以看到这可能不是最好的方法,考虑到从子对象设置父对象的状态,但是这对于在父组件上设置默认值是一个很好的解决方案,该组件在不同子对象之间可以重复使用。

Im all ears stack overflow 我所有的耳朵都堆栈溢出

I think the problem is that setState does both updates at the same time (batches them) meaning the same initial state is used when merging both partial states. 我认为问题在于setState执行两个更新(批处理),这意味着合并两个部分状态时会使用相同的初始状态。 You need to use updater function as shown by kind user : 您需要使用updater函数,如亲切的用户所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM