Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How function exist after component has been unmounted

My Doubt is related to using timer in react component, as per my understanding once component unmount its all properties/methods will not exist after that.

As per DOC:

componentWillUnmount() is invoked immediately before a component is unmounted and destroyed. Perform any necessary cleanup in this method, such as invalidating timers, canceling network requests, or cleaning up any DOM elements that were created in componentDidMount.

Check this snippet:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: 1};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      3000
    );
  }

  componentWillUnmount() {
    //clearInterval(this.timerID);
  }

  tick() {
     console.log('called', this.props.no);
  }

  render() {
    return (
      <div>
        <h1>Clock {this.props.no}</h1>
      </div>
    );
  }
}

class App extends React.Component {
  
  constructor(){
     super();
     this.state = {unMount: false}
  }
  
  click(){
     console.log('unmounted successfully');
     this.setState({unMount: !this.state.unMount})
  }
  
  render(){
    return (
       <div>
          <button onClick={() => this.click()}>Unmount first</button>
           {!this.state.unMount && <Clock no={1}/>}
           <Clock no={2}/>
       </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='root'/>

Here i am rendering two clock component and unmounting the first one onclick of button that is happening successfully and it's updating the DOM also, even after unmounting the first component timer is printing the props values properly by console.log().

I am not clearing the Timer in componentWillUmount:

componentWillUnmount() {
    //clearInterval(this.timerID);
}

My Doubt is:

this.timerID = setInterval(
   () => this.tick(),
   3000
);

tick() {
   console.log('called', this.props.no);
}

I am passing a class method as callback in timer so once component has been unmounted how tick function exist, How this timer is resolving this keyword and the tick function after the component unmounted? How this.props.no is having the correct value? why it's not throwing the error:

can't read tick of undefined or tick is not defined

How it is maintaining the references to these functions?

Help me what i am missing here, please provide any reference or example.

like image 618
Mayank Shukla Avatar asked Dec 12 '25 05:12

Mayank Shukla


2 Answers

Unlike C++, you cannot explicitly delete objects from memory (aka 'destroy') in JavaScript. You can only delete references to them. Once no more references point to the object or its properties, it is eligible for garbage collection. Only then the garbage collector actually destroys it.

Memory Management — JavaScript

In this case, even after unmount you still have valid references to the object and its properties in your closures (this.tick, this.props, etc). At some point, after execution, they will go out of scope, then later your component will be destroyed and the memory will be released.

like image 170
Dmitry Shuranov Avatar answered Dec 14 '25 18:12

Dmitry Shuranov


Doing a lot of digging into the React code , I found the following doc

and the code from the react github page

function unmountComponentFromNode(instance, container) {
  if (__DEV__) {
    ReactInstrumentation.debugTool.onBeginFlush();
  }
  ReactReconciler.unmountComponent(
    instance,
    false /* safely */,
    false /* skipLifecycle */,
  );
  if (__DEV__) {
    ReactInstrumentation.debugTool.onEndFlush();
  }

  if (container.nodeType === DOCUMENT_NODE) {
    container = container.documentElement;
  }

  // http://jsperf.com/emptying-a-node
  while (container.lastChild) {
    container.removeChild(container.lastChild);
  }
}

This suggest that React will remove the Components from the UI and ready them for Garbage Collection, however even when the DOM elements have been removed the class instances are not so the methods, props still exist and hence setInterval continues to be executed.

Only when the references to this.ticks() and this.props are not longer used, they will be eligible for garbage collection

JavaScript values are allocated when things (objects, strings, etc.) are created and "automatically" freed when they are not used anymore. The latter process is called garbage collection.

like image 39
Shubham Khatri Avatar answered Dec 14 '25 17:12

Shubham Khatri



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!