我的应用程序表明内存泄漏与componentWillmount()有问题

问题描述 投票:0回答:3

您好我的组件将挂载和卸载有问题,我不确定这是否只是我登录和退出不同的帐户来测试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;
        }   

并且我一直在收到错误,我想知道为什么我认为这与我多次登录有关,但我不希望这个错误出现,无论如何。

reactjs firebase authentication components
3个回答
3
投票

虽然上面的人都是正确的,但我建议你检查一下:

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

因为那是装载你正在做的是反模式,不推荐。

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

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

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

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

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


0
投票

首先componentWillMount已被弃用,你应该只在componentDidMount上做这些东西,因为这是实际安装的时候。

其次,在你的firebase回调中,你想要在尝试执行setState之前检查组件是否已挂载。你已经用你的this._isMounted财产制作了旗帜,但你实际上没有检查它。它应该是

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

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

0
投票

这是因为你的onAuthStateChanged电话是异步的。所以有可能发生以下情况:

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

你可以做的是在调用this._isMounted之前为你的旗帜setState添加一个支票

© www.soinside.com 2019 - 2024. All rights reserved.