最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How function exist after component has been unmounted - Stack Overflow

programmeradmin0浏览0评论

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

As per DOC:

ponentWillUnmount() is invoked immediately before a ponent 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 ponentDidMount.

Check this snippet:

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

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

  ponentWillUnmount() {
    //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=".1.0/react.min.js"></script>
<script src=".1.0/react-dom.min.js"></script>

<div id='root'/>

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

As per DOC:

ponentWillUnmount() is invoked immediately before a ponent 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 ponentDidMount.

Check this snippet:

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

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

  ponentWillUnmount() {
    //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./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='root'/>

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

I am not clearing the Timer in ponentWillUmount:

ponentWillUnmount() {
    //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 ponent has been unmounted how tick function exist, How this timer is resolving this keyword and the tick function after the ponent 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.

Share Improve this question edited Jul 18, 2017 at 10:05 Mayank Shukla asked Jul 18, 2017 at 9:40 Mayank ShuklaMayank Shukla 105k19 gold badges162 silver badges145 bronze badges 2
  • 1 ..as per my understanding once ponent unmount its all properties/methods will not exist after that. That's not quite correct. Technically React ponent is a JS class (function) and mounting make connection between this class and respective DOM stuff. When ponent is unmounted only this connection is destroyed but the respective JS class and its props/methods are still exist. – hindmost Commented Jul 18, 2017 at 10:15
  • @hindmost thanks, but if that code will still exist then it should create the memory issue since ponent get render and unmount very frequently when we visit different pages correct? another thing is, till what moment that code will be available because i waited for 10 mins but still that is printing the values properly, it should throw error after some time. – Mayank Shukla Commented Jul 18, 2017 at 10:29
Add a ment  | 

3 Answers 3

Reset to default 8

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 ponent will be destroyed and the memory will be released.

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./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.

This is outside the way react works and more just javascript. You should be clearing your interval on the ponentWillUnmount. It even says in the docs:

Perform any necessary cleanup in this method, such as invalidating timers

Your code is mented out? Is that not the issue here?

  ponentWillUnmount() {
    //clearInterval(this.timerID);
  }
发布评论

评论列表(0)

  1. 暂无评论