Javascript 取消组件中的任务将卸载

Javascript 取消组件中的任务将卸载,javascript,reactjs,firebase,gatsby,Javascript,Reactjs,Firebase,Gatsby,这是一个常见的问题,但我知道原因,通常可以很快解决 但是,在这种情况下,我似乎无法卸载我的ReactJS和GatsbyJS应用程序中的任务 下面的代码正在侦听Firebaseauth更改,而withsetState正在state中提供auth用户详细信息 _initFirebase = false; constructor(props) { super(props); this.state = { authUser: null }; } firebaseInit = (

这是一个常见的问题,但我知道原因,通常可以很快解决

但是,在这种情况下,我似乎无法卸载我的ReactJS和GatsbyJS应用程序中的任务

下面的代码正在侦听Firebase
auth
更改,而with
setState
正在
state
中提供
auth
用户详细信息

_initFirebase = false;

constructor(props) {
  super(props);

  this.state = {
    authUser: null
  };
}

firebaseInit = () => {
  const { firebase } = this.props;
  if (firebase && !this._initFirebase) {
    this._initFirebase = true;

    this.listener = firebase.onAuthUserListener(
      authUser => {
        localStorage.setItem('authUser', JSON.stringify(authUser));
        this.setState({ authUser });
      },
      () => {
        localStorage.removeItem('authUser');
        this.setState({ authUser: null });
      }
    );
  }
};

componentDidMount() {
  this.setState({
    authUser: JSON.parse(localStorage.getItem('authUser'))
  });

  this.firebaseInit();
}

componentDidUpdate() {
  this.firebaseInit();
}

componentWillUnmount() {
  this.listener && this.listener();
}
在的控制台中导致错误

Warning: 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.
    in WithAuthentication (created by Context.Consumer)
    in Component (created by Layout)
    in Layout (created by SigninPage)
    in SigninPage (created by HotExportedSigninPage)
    in AppContainer (created by HotExportedSigninPage)
    in HotExportedSigninPage (created by PageRenderer)
据我所知,我有足够的
卸载
这些
设置状态
任务在
组件中将卸载


您能解释一下我可能遗漏了什么吗?

问题是您试图在组件卸载后设置状态。。。 无法在componentWillUnmount中设置状态

针对您的用例的解决方案:

initFirebase = false;

constructor(props) {
  super(props);

  this.state = {
    authUser: null
  };
  // this prop to check component is live or not
  this.isAmAlive = false;

}



firebaseInit = () => {
  const { firebase } = this.props;
  if (firebase && !this._initFirebase) {
    this._initFirebase = true;

    this.listener = firebase.onAuthUserListener(
      authUser => {
        localStorage.setItem('authUser', JSON.stringify(authUser));
          //check component is live or not if live update the component
          if(this.isAmAlive){
             this.setState({ authUser });
           }

      },
      () => {
        localStorage.removeItem('authUser');
         //check component is live or not if live update the component
         if(this.isAmAlive){
             this.setState({ authUser : null });
         }
      }
    );
  }
};

componentDidMount() {

  this.isAmAlive =true;

  this.setState({
    authUser: JSON.parse(localStorage.getItem('authUser'))
  });

  this.firebaseInit();
}

componentDidUpdate() {
  this.firebaseInit();
}

componentWillUnmount() {
  this.isAmAlive = false;
  this.listener && this.listener();
}

我对firebase不太熟悉,这是不是
this.listener
实际上是一个“退订者”?否则我不明白为什么要在unmount hook
中调用“listener”。listener
是从一个单独的文件中调用的,名为
firebase.onAuthUserListener