Under Adding Lifecycle Methods to a Class in the official Facebook docs for React, it's mentioned:
5) If the Clock component is ever removed from the DOM, React calls the componentWillUnmount() lifecycle hook so the timer is stopped.
Just trying to understand how? I get that React knows when it's about to insert the component in the DOM, so it can callcomponentDidMount
life cycle hook then.
But for componentWillUnmount
it just says "ever removed from the DOM". Seems to suggest it's the real DOM not React DOM. One might as well remove the component with javaScript/jQuery and componentWillUnmount
should fire.
How exactly does React know the component has been removed from the real DOM? Could there be a watcher?
Thanks
There is no watcher on the actual DOM. Everytime the render function of a component gets called, the Virtual DOM gets re-build. If a component is no longer necessary, it gets removed from the virtual DOM.
A diffing algorithm identifies those parts of the actual DOM that need to be changed for the actual DOM to be a reflection of the virtual DOM: some components will have to be added to the actual DOM (= called mounting), other components will have to be removed (= unmounting). This whole process is called reconciliation.
It is because of this reconciliation process, that React knows which components are to be removed from the actual DOM. Right before the component is removed, React calls the componentWillUnmount() lifecycle hook.
If another script (Javascript or jQuery) causes the removal of a certain component from the actual DOM, React will never notice it and therefore will not call the componentWillUnmount() lifecycle hook.
This is not true. IF you do manually remove a component from the DOM it will not fire componentWillUnmount
..
It happens only via Virtual DOM, level if the component is not present anymore:
// Unmount children that are no longer present.
for (name in prevChildren) {
if (
prevChildren.hasOwnProperty(name) &&
!(nextChildren && nextChildren.hasOwnProperty(name))
) {
prevChild = prevChildren[name];
removedNodes[name] = ReactReconciler.getHostNode(prevChild);
ReactReconciler.unmountComponent(
prevChild,
false /* safely */,
false /* skipLifecycle */,
);
}
}
https://github.com/facebook/react/blob/5c6a496d98b80d19d851c2ec3a56d760b7118a50/src/renderers/shared/stack/reconciler/ReactChildReconciler.js
unmountComponent
will then call componentWillUnmount
.
I manually tested componentWillUnmount
by opening the devtools and removing some components that had componentWillUnmount
lifecycle method.
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