I have a React
Parent
and Child
component. The Child has to be able to update the state of the Parent component. However, I have the issue that my Parent is unmounted
when the Child wants to update the Parent
, and I'm not sure why or how to fix that?
I'm pasting the simplified code that is relevant to the issue. In this case, the child wants to update the page Title
that is rendered in the Parent
. But sadly, in the componentDidMount()
of the Child (where this update happens) the Parent is already unmounted
.
The index.js
loads the Child
directly but it wraps the Parent
component around it. I guess that has something to do with the Parent
component unmounting?
Parent:
type Props = TranslationProps & {
Component: any
};
type State = {
setTitle: string
};
export class Layout extends Component<Props, State> {
_isMounted = false;
constructor(props:Props) {
super(props);
this.state = {
setTitle: ""
};
}
componentDidMount() {
this._isMounted = true;
}
componentWillUnmount() {
this._isMounted = false;
}
render() {
const { Component, ...restProps } = this.props;
return (
<Component
setTitle={title=> this._isMounted && this.setState({ setTitle: title})}
isMounted={this._isMounted}
{...restProps}
/>
);
}
}
Child:
type Props = TranslationProps & {
setTitle: (data: string) => void,
isMounted: boolean
};
componentDidMount() {
const { t } = this.props;
if(this.props.isMounted) {
this.props.setTitle("Test title");
}
}
Index:
const unwrap = component => {
if(component.WrappedComponent) {
return unwrap(component.WrappedComponent);
}
return component;
}
let reactMounts = document.querySelectorAll("[data-react]");
for (let reactMount of reactMounts) {
let Component = Components[reactMount.dataset.react];
let UnwrappedComponent = unwrap(Component);
console.log("Rendering", Component, " (", UnwrappedComponent, ") to ", reactMount);
let data = {
...reactMount.dataset,
Component
};
delete data.react;
render(
React.createElement(Components['Layout'], data),
reactMount
);
}
Reason: Accoring to React life-cycle, Child Component rendered before ComponentDidMount (where _isMounted = true). So, I guess the this._isMounted variable in setTitle props always = false => bug.
Solution: I recommend that you should create callback function in class, after that passing in setTitle props.