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

javascript - React Component with Memory Leak - Stack Overflow

programmeradmin3浏览0评论

I have a piece of legacy code, which renders a react ponent on the server on every request, which makes it obvious there is a memory leak. I have corner the problem up to this code:

  ponentWillMount: 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));
  },

I believe that on every request the this object is storing a new listener, but I don't get why the this element is not being marked as garbage when the rendering of the ponent is done.

I have a piece of legacy code, which renders a react ponent on the server on every request, which makes it obvious there is a memory leak. I have corner the problem up to this code:

  ponentWillMount: 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));
  },

I believe that on every request the this object is storing a new listener, but I don't get why the this element is not being marked as garbage when the rendering of the ponent is done.

Share Improve this question asked Oct 20, 2016 at 16:27 Mr. GoferitoMr. Goferito 7,0214 gold badges27 silver badges27 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 8

You need to unbind the authChange handler before the ponent is unmounted. You can do this in ponentWillUnmount.

Since you're creating the handler function using the first props that are passed in, you should save it to a property so you can unbind it later:

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

    this.authChange = function () {
      console.log('user authenticated:', this.state.isAuthenticated);
      return this.state.isAuthenticated
              ? onLogin(this.state)
              : onLogout(this.state);
    }.bind(this);

    this.on('authChange', this.authChange);
  },

  ponentWillUnmount: function () {
      this.off('authChange', this.authChange);
      this.authChange = null;
  }

Note that when I saw this.on I thought you might be using jQuery but it's not clear how that would be the case. My answer uses this.off to detach the event listener but you should use whatever the corresponding method is in your framework.

I would move your function into ponentDidMount and add cleanup on ponentWillUnmount

Important: ponentWillMount is called on the server and client, but ponentDidMount is only called on the client.

If you’re using eventListeners, setInterval or other functions that needs to be cleaned, put them in ponentDidMount. The server will not call ponentWillUnmount and is usually the cause of memory leaks.

发布评论

评论列表(0)

  1. 暂无评论