мое приложение указало на утечку памяти из-за проблемы с componentWillmount () - PullRequest
0 голосов
/ 19 февраля 2019

Здравствуйте, у меня проблемы с компонентом, который примонтирует и размонтирует, и я не уверен, что это просто вход в систему и выход из нее с разными учетными записями для проверки отображения имени в firebase, но я не совсем уверен, что получаю это сообщение после подписанияи около 3 раз

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.

вот мой код с помощью componentWillMount и UnMount

    _isMounted = false;

      constructor() {
        super();
        this.state = {
          authenticated: false,
          user: null ,
          loading: true
        }
      }
        componentWillMount() {
          this._isMounted = true;

          firebase.auth().onAuthStateChanged(user => {

            if (user) {
                this.setState({
                  authenticated: true,
                  currentUser: user,
                  loading: false
                });
            } else {
              this.setState({
                authenticated: false,
                currentUser: null,
                loading: false
              });
            }
          });
        }

        componentWillUnmount() {
          this._isMounted = false;
        }   

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

Ответы [ 3 ]

0 голосов
/ 19 февраля 2019

Это потому, что ваш onAuthStateChanged вызов асинхронный.Таким образом, возможно следующее:

  1. Ваш компонент отключен
  2. Обратный вызов auth() происходит
  3. Все еще пытается выполнить код setState,который на данный момент является несмонтированным компонентом.

Что вы можете сделать, это добавить проверку вашего флага this._isMounted перед вызовом setState

0 голосов
/ 19 февраля 2019

Даже если парни правы выше, я бы посоветовал вам проверить:

https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html

, так как это установлено, что вы делаете, есть antipattern и не рекомендуется.

Правильным способом было бы использовать эту makeCancelable функцию из статьи и сделать отменяемыми свои обещания setState, например

this.cancelablePromise = makeCancelable(
  new Promise(r => this.setState({
              authenticated: true,
              currentUser: user,
              loading: false
            }))
);

После создания этих обещаний просто сделайте что-то вроде:

componentWillUnmount() {
    this.cancelablePromise.cancel();
}

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

0 голосов
/ 19 февраля 2019

Первый componentWillMount устарел, вы просто должны сделать это на componentDidMount, потому что именно тогда он НАСТОЯТЕЛЬНО смонтирован.

Во-вторых, в вашем обратном вызове firebase вы захотите проверить, является ли компонентмонтируется перед попыткой сделать setState.Вы уже сделали флаг со своим свойством this._isMounted, но на самом деле вы его не проверяете.Это должно быть

   firebase.auth().onAuthStateChanged(user => {

      if (this._isMounted){
         // do setState stuff with user here
      }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...