I have a root component that initialises and hosts the entire application and that when simplified looks like
class App extends React.Component {
componentDidMount() {
// initialisation here
}
componentWillUnmount() {
// I expect this to never happen
}
render() {
// the whole app is rendered here
}
}
It's rendered on the page as simple as just (I do it just once, that script runs on page load and never is called again)
ReactDOM.render(<App />, domElement);
What I have discovered recently is that sometimes (extremely rarely) the App
's componentWillUnmount
is getting called.
Last time it happened on the mobile chrome 67, but also was observed on a desktop one as well.
I captured that event with a dummy raven.captureMessage('application will unmount');
(where raven
is a sentry client), so at this moment I don't have any more details yet.
But it is totally surprising to me: under what circumstances can the root component be unmounted by react? No JS touches the react-managed DOM, the last occurrence happened on a phone of a person I know and it's a regular chrome browser without any modifications.
I talked to the person - and they mentioned that the application visually look normal (but for obvious reasons it did not function properly - since I deinitialise things there).
Another odd moment is that I also log if componentDidMount
happened more than once (via a module-scoped variable) for that component, and it was not called.
So to summarise: the componentWillUnmount
was called, the DOM node has not been removed, the consecutive componentDidMount
was not called (this sequence sounds unbelievable to me, but that's what I observed).
Another important thing: for the latest case it happened exactly after the chrome un-hibernated the tab (chrome puts a tab in hibernation when it is hibernated or when other tabs need ram/cpu).
Am I missing something here?
One circumstance is when you render another component into the root container with ReactDOM
:
const rootElement = document.getElementById('root');
const OtherComponent = () => <p>test</p>;
class App extends Component {
componentWillUnmount() {
console.log('will unmount');
}
handleRenderOtherComponent = () => {
ReactDOM.render(<OtherComponent />, rootElement);
};
render() {
return (
<button onClick={this.handleRenderOtherComponent}>
remove root
</button>
);
}
}
ReactDOM.render(<App />, rootElement);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With