【发布时间】:2019-03-18 21:06:03
【问题描述】:
我有一个 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.assign 创建的 state.commodity 的全新克隆来更新状态,但这没有解决问题。
这个问题很奇怪,因为 ProductProperties 组件已经被另一个父组件使用了一段时间,而没有出现这个问题。我发现 ProductForm 和其他没有出现此问题的父组件之间没有区别。 (原本 ProductForm 的父 CreateProduct 是用 getDerivedStateFromProps 管理其内部状态,但即使我将其更改为使用 componentWillReceiveProps,问题仍然存在。
【问题讨论】:
-
代码和解释看起来很有说服力。你为什么不把你的问题写成
codesandbox,让我们看看一个完整的、可复制的代码环境 -
您能否分享一下 ProductForm 组件的预初始化状态,否则很难向您推荐可能的解决方案。如果可以共享两个组件代码就更好了
-
谢谢,我已经添加了更多细节——我认为关键是 ProductProperty 渲染在调用时总是可以正常工作——问题是它并不总是在其父状态更改时调用。如果没有进一步的想法,我可以考虑在沙箱中获取一些工作代码。
标签: reactjs