我的应用程序指示内存泄漏使componentWillmount()遇到问题

时间:2019-02-19 00:38:12

标签: reactjs firebase authentication components

你好,我在安装和卸载组件时遇到麻烦,我不确定这是否是我使用其他帐户登录和注销以测试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.

这是我的组件WillMount和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 :(得分:3)

即使上面的人是正确的,我还是建议您检查一下:

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

由于您正在执行isMounted操作,因此存在反模式,因此不建议使用。

正确的方法是使用本文中的makeCancelable函数,并使setState可取消承诺,即

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

创建这些承诺后,只需执行以下操作:

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

请记住,以上所有内容仅供您参考,可能需要进行一些调整,但如果正确执行,将会解决问题。

答案 1 :(得分:0)

不建议使用第一个componentWillMount,您应该在componentDidMount上执行该操作,因为这是实际安装的时间。

第二,在您的Firebase回调中,您需要在尝试执行setState之前检查组件是否已安装。您已经使用this._isMounted属性创建了该标志,但是实际上并未对其进行检查。应该是

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

      if (this._isMounted){
         // do setState stuff with user here
      }

答案 2 :(得分:0)

这是因为您的onAuthStateChanged呼叫是异步的。因此有可能发生以下情况:

  1. 您的组件已卸载
  2. 发生auth()回调
  3. 仍然尝试运行setState代码,该代码目前是未安装的组件。

您可以做的是在致电this._isMounted之前添加对标记setState的检查