Writing in the front

  • React code generates the following error
Can't perform a React state update on an unmounted component. This is a no-op......
Copy the code
  • This article first reviews what a memory leak is and then looks at two demos that observe how a memory leak occurs in React.

What is a memory leak

  • The program needs memory to run. The operating system or runtime must supply memory whenever the program requests it.

  • For continuously running daemons, memory that is no longer needed must be released in a timely manner. Otherwise, the memory footprint increases, which can affect system performance at best or cause process crashes at worst.

  • If memory that is no longer needed is not released in time, it is called a memory leak.

Several memory leaks are common in JavaScript

  • Memory leak caused by global variables
function leaks(){  
    leak = '* * *'; // Leak becomes a global variable and is not recycled
}
Copy the code
  • Memory leaks caused by closures
var leaks = (function(){  
    var leak = '* * *';// is referenced by closures and will not be recycled
    return function(){
        console.log(leak);
    }
})()
Copy the code
  • Memory leaks caused by events not cleared when the DOM is emptied or deleted
document.querySelector("#demo").addEventListener('click', myFunction);

var para1=document.querySelector("#demo");

para1.parentNode.removeChild(para1);

Copy the code

If we had destroyed the PARA1 node without canceling the click method, we would have caused a memory leak.

The right thing to do:

document.querySelector("#demo").addEventListener('click', myFunction);

// We need to clear the mounted click method before deleting the node
document.querySelector("#demo").removeEventListener("click", myFunction);

var para1=document.querySelector("p1");

para1.parentNode.removeChild(para1);
Copy the code
  • Extended reading, you can have a careful look at ruan Yifeng teacher’s related articles
  • www.ruanyifeng.com/blog/2017/0… (Ruan Yifeng)

To learn more about react’s memory leaks, check out the following demos

The Demo 1:

componentWillMount: function () {
    var onLogin = this.props.onLogin || function () {},
        onLogout = this.props.onLogout || function () {};

    this.on('authChange'.function () {
      console.log('user authenticated:'.this.state.isAuthenticated);
      return this.state.isAuthenticated
              ? onLogin(this.state)
              : onLogout(this.state);
    }.bind(this));
  },
Copy the code
  • The above example is on Stack OverflowcomponentWillMountIt’s time to mount itauthChangeReact:

Can’t perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, Cancel all subscriptions and asynchronous tasks in the componentWillUnmount Method”

  • We cannot set state after component destruction to prevent memory leaks

What do we need to do?

  • Add the following code
  componentWillUnmount: function () {
      this.off('authChange'.this.authChange);
      this.authChange = null;
  }
Copy the code

This is obviously the case when the dom structure is destroyed and the event is not cleared, so we need to clean up the mount method at componentWillUnmount

React Memory leaks and solutions

  • Memory leaks are mentioned here, when we use event binding, setInterval, setTimeOut, or some function that is not cleared before component destruction. Here we manually componentWillUnmount to remove the associated methods.

  • According to:

    • I would move your function into componentDidMount and add cleanup on componentWillUnmount
    • Important: componentWillMount is called on the server and client, but componentDidMount is only called on the client.
    • If you’re using listeners, intervals or other functions that needs to be cleaned, put them in componentDidMount. The server will not call componentWillUnmount and is usually the cause of memory leaks.
  • Stackoverflow.com/questions/4…

The Demo 2:

  • The following is a common case:
this.pwdErrorTimer = setTimeout(() = > {
    this.setState({
        showPwdError:false})},1000);
Copy the code

A timer delay setting state is set, but during this delay the component has been destroyed, causing this problem

  • Solutions:
  • Use the lifecycle hook function: componentWillUnmount
componentWillUnmount(){
    clearTimeout(this.pwdErrorTimer);
    clearTimeout(this.userNameErrorTimer);
}
Copy the code

If react16.8+ is introduced

  • We can use useEffect() to solve most memory leaks.

Two important concepts are mentioned in the document

Why return a function in effect?

  • This is the optional clearing mechanism for Effect. Each effect can return a cleanup function. This puts the logic for adding and removing subscriptions together. They are all part of Effect.

React when to remove an effect?

  • React performs cleanup operations when components are uninstalled. As you learned earlier, an effect is executed every time it is rendered. This is why React cleans up the previous effect before executing the current effect. We’ll talk later about why this helps avoid bugs and how to skip this behavior when you encounter performance problems.

prompt

If you’re familiar with React class lifecycle functions, you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount.

Derived from the reading

Questions about whether promise requests cause memory leaks

1, Does never resolved promise cause memory leak?

  • Does never resolved promise cause memory leak?
  • The original problem is above, you can have a look

Memory leaks in Loops with Promise?

  • Loop a promise and cause a memory leak?