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

标签 javascript reactjs lifecycle children direction

好吧,这个问题有点棘手。我一直在思考这是否是正确的概念,考虑到 React 应该是一种单向数据流,从父级到子级,而不是相反。但无论如何我想发布这个问题,这样我就能得到不同的意见,甚至可能找到一种让它发挥作用的方法。

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

简而言之,我试图在 child 的 componentidMount() 方法上触发我的父方法,并且它有效,但是,如果有多个 child 尝试执行此操作,该方法会被调用两次,但它只使用第二个 child 的数据集。

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

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 中发送的数据更新状态。再次,我可以看到,考虑到我从子组件设置父组件的状态,这可能不是最好的方法,但对于在父组件上设置默认值(该组件会被不同的子组件大量重用)来说,这将是一个很好的解决方案。

我洗耳恭听堆栈溢出

最佳答案

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

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

关于javascript - 从多个子组件的 componentDidMount() 同步更新父组件状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53622427/

相关文章:

vue.js - 使用Mounted()或created()VueJs + Electron内的ipcRenderer.on()时,文本在屏幕上未更改

javascript - 如何在node.js中识别IPV6私有(private)地址和环回地址?

javascript - 可选链接在 create-react-app 中不起作用

security - react +路由+安全

javascript - 使用 NextJS 静态预渲染最流行的查询

java - spring bean 的生命周期是什么?

javascript - SetTimeout 在 jQuery 中不能正常工作

javascript - 事件处理程序等待来自其他事件处理程序的 AJAX 调用

javascript - D3 将更新选择限制为具有实际更改的条目?

ios - 在 iOS 上删除钥匙串(keychain)数据