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

时间:2018-10-14 05:30:46

标签: reactjs

我有一个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

    }


}

在两个组件的初始呈现时,ProductProperty都会成功接收ProductForm的state.commodity。在ProductProperty中编辑输入字段时,组件将调用props.parentEvtHandler(代表ProductForm中更改状态的函数)。发生此调用时,ProductForm会正确更新其状态-调用其render()并将其对state.commodity进行引用,以表明状态已正确更新。

问题在于,state.commodity的新值未传递给ProductProperties。实际上,由于没有触发登录该组件的componentWillReceiveProps,因此似乎根本没有更新ProductProperties。

在更新ProductForm的父级CreateProduct时,道具正确地流向ProductProperties,调用componentWillReceiveProps,并且一切都正确呈现。

我尝试过的一件事: 由于仅对对象的属性进行了对state.commodity的更改,我认为React无法看到该对象已更改,因此尝试使用由Object.assign创建的全新的state.commodity克隆来更新状态。不能解决问题。

这个问题很奇怪,因为另一个父组件在没有发生此问题的情况下已经使用了ProductProperties组件一段时间。我看不到ProductForm和其他没有出现此问题的父组件之间的区别。 (最初,ProductForm的父级CreateProduct使用getDerivedStateFromProps管理其内部状态,但是即使我将其更改为使用componentWillReceiveProps,问题仍然存在。)

1 个答案:

答案 0 :(得分:0)

我发现某种可以解决问题的方法,尽管我认为这不能解决根本原因。

当我更改ProductForm使其不再通过它的handlePropertiesFormChange的预绑定副本时,而是在每个render()绑定一个新副本时,问题就消失了。问题代码:

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

没有出现此问题的代码:

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

我认为重新绑定只是掩盖了核心问题-通过新绑定的函数,React认为有必要将新的props传递给ProductProperty,但它应该看到这种需求仅基于state.commodity的变化。这也解释了为什么使用ProductProperty的其他组件没有出现问题(它们重新绑定了功能)。