首页 文章

React组件不会将更改状态传递给子级

提问于
浏览
0

我有一个React 16.5.2组件,它将其部分状态传递给子组件,但是当父状态发生更改时,子组件没有得到更新(子组件的componentWillReceiveProps没有被调用) .

以下是基础知识:

class ProductForm extends React.Component {
    constructor(props){
        super(props)
        this.handlePropertiesFormChange.bind(this)
        ...
    }

    handlePropertiesFormChange(commodityProps) {
       const comm = this.state.commodity
       comm.properties = commodityProps
       this.setState({
         commodity: comm,
       })
    }

    render() {
        return(
            <ProductProperties
                commodity={ this.state.commodity }
                parentEvtHandler={ this.handlePropertiesFormChange }
            />
        )
    }

}

class ProductProperties extends React.Component {
    constructor(props) {
        super(props)
        this.state = { showDrugCatalog: false, synonyms: props.commodity.getSynonyms() || '' }
    }

    componentWillReceiveProps(nextProps) {
        // this logging does not appear after calling this.props.parentEvtHandler()
        // when ProductForm's parent CreateProduct is updated, 
        // this method is called and everything renders properly
        console.log("==== cWRP in productProperties, nextProps =  ", nextProps)
        ....
    }
}

    render() {
        // numerous calls to various methods of this.props.commodity,
        // which all work fine whenever this component is updated

    }


}

在初始渲染两个组件时,ProductProperties成功接收ProductForm的state.commodity . 在ProductProperties中编辑输入字段时,组件调用props.parentEvtHandler(表示更改状态的ProductForm中的函数) . 当这个调用发生时,ProductForm会正确更新其状态 - 调用它的render(),并且它对state.commodity的引用表明状态已正确更新 .

问题是,state.commodity的新值未传递给ProductProperties . 实际上,它似乎根本没有更新ProductProperties,因为不会触发登录该组件的componentWillReceiveProps .

更新ProductForm的父CreateProduct时,props正确地流向ProductProperties,调用componentWillReceiveProps,并且所有内容都正确呈现 .

我试过的一件事:由于对state.commodity的更改只是对象的属性,我认为React没有看到这个对象发生了变化,尝试使用Object创建的全新的state.commodity克隆更新状态.assign,但这并没有解决问题 .

这个问题很奇怪,因为ProductProperties组件已经被不同的父组件使用了一段时间,而不会发生此问题 . 我发现ProductForm与没有出现此问题的其他父组件之间没有区别 . (最初,ProductForm的父CreateProduct使用getDerivedStateFromProps管理其内部状态,但即使我将其更改为使用componentWillReceiveProps,问题仍然存在) .

1 回答

  • 0

    我找到了一些解决问题的方法,虽然我不认为它解决了根本原因 .

    当我更改ProductForm以便它不再传递它的handlePropertiesFormChange的预绑定副本,而是每次render()绑定一个新副本时,问题就会消失 . 问题代码:

    <ProductProperties
         commodity={ this.state.commodity }
         parentEvtHandler={ this.handlePropertiesFormChange }
    />
    

    没有出现此问题的代码:

    <ProductProperties
         commodity={ this.state.commodity }
         parentEvtHandler={ this.handlePropertiesFormChange.bind(this) }
    />
    

    我认为重新绑定只是掩盖核心问题 - 使用新绑定的函数,React认为需要将新的道具传递给ProductProperties,但它应该看到仅基于state.commodity更改的需求 . 这也解释了为什么使用ProductProperties的其他组件没有表现出问题(他们重新绑定了这个功能) .

相关问题