我有一个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 回答
我找到了一些解决问题的方法,虽然我不认为它解决了根本原因 .
当我更改ProductForm以便它不再传递它的handlePropertiesFormChange的预绑定副本,而是每次render()绑定一个新副本时,问题就会消失 . 问题代码:
没有出现此问题的代码:
我认为重新绑定只是掩盖核心问题 - 使用新绑定的函数,React认为需要将新的道具传递给ProductProperties,但它应该看到仅基于state.commodity更改的需求 . 这也解释了为什么使用ProductProperties的其他组件没有表现出问题(他们重新绑定了这个功能) .