Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does React know the component is removed from the DOM?

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

like image 445
Talha Awan Avatar asked Jul 09 '17 13:07

Talha Awan


2 Answers

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.

like image 128
jpuntd Avatar answered Nov 02 '22 10:11

jpuntd


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.

like image 31
enapupe Avatar answered Nov 02 '22 10:11

enapupe