I have a React 16.5.2 component that passes part of its state to a child component, but when the parent state changes, the child is not getting updated (the child's componentWillReceiveProps is not getting called).
Here are the basics:
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
}
}
On initial render of both components, ProductProperties successfully receives ProductForm's state.commodity. When input fields are edited in ProductProperties, the component calls props.parentEvtHandler (which represents the function in ProductForm that changes state). When this call happens, ProductForm correctly updates its state -- its render() is called and references it makes to state.commodity show that the state was correctly updated.
The problem is, the new value of state.commodity is not passed to ProductProperties. In fact, it appears it is not updating ProductProperties at all, since logging on that component's componentWillReceiveProps is not triggered.
When ProductForm's parent CreateProduct is updated, the props flow correctly to ProductProperties, componentWillReceiveProps is called, and everything renders correctly.
One thing I tried: Since changes to state.commodity are only being made to a property of the object, I thought React was failing to see this object has having changed, tried updating state with a totally new clone of state.commodity created with Object.assign, but this did not fix the problem.
This problem is strange because the ProductProperties component has been in use for some time by a different parent component where this problem does not occur. I see no difference between ProductForm and the other parent component that does not exhibit this problem. (Originally ProductForm's parent CreateProduct was managing its internal state with getDerivedStateFromProps, but even when I changed this to use componentWillReceiveProps, the problem still exists).
codesandboxout of your problem and let us see a complete, replicable code environment - Prasanna