0

У меня есть фрагмент устаревшего кода, который на каждом запросе оказывает реагирующий компонент на сервер, что делает очевидным наличие утечки памяти. У меня есть угол проблема до этого кода:React Component with Memory Leak

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

Я считаю, что каждый просить this объекта хранение нового слушателя, но я не получаю, почему this элемента не помечается как мусор, когда выполняется рендеринг компонента.

ответ

2

Перед отсоединением компонента необходимо развязать обработчик authChange. Вы можете сделать это в componentWillUnmount.

Поскольку вы создаете функцию обработчика, используя первый реквизит, которые передаются в системе, вы должны сохранить его в собственность, так что вы можете отвязать его позже:

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

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

Обратите внимание, что, когда я увидел, я подумал this.on вы можете использовать jQuery, но неясно, как это будет. Мой ответ использует this.off, чтобы отсоединить прослушиватель событий, но вы должны использовать все, что соответствует вашему методу.

+0

Но не должен ли компонент 'this' быть помечен как мусор, когда функция' renderToString() 'будет завершена? –

2

Я бы переместить функцию в componentDidMount и добавить очистку на componentWillUnmount

Важно: componentWillMount вызывается на сервере и клиента, но componentDidMount вызывается только на клиента.

Если вы используете eventListeners, setInterval или другие функции, которые необходимо очистить, поместите их в componentDidMount. Сервер не будет звонить componentWillUnmount и обычно является причиной утечки памяти.