如何在react中删除新的firebase onAuthStateChanged侦听器

时间:2016-06-26 12:02:58

标签: reactjs firebase react-router firebase-authentication

我正在使用react-router在反应式网络应用中实现firebase auth。

用户使用弹出式登录登录(在/登录)Facebook或Google,然后如果成功,我将路由到主应用程序(/)。在主应用程序组件中,我监听身份验证状态更改:

  componentWillMount() {
    this.authListener = this.authListener.bind(this);
    this.authListener();
  }

authListener侦听身份验证更改:

authListener() {
    firebase.auth().onAuthStateChanged((user) => {
      if (user) {
        console.log('user changed..', user);
        this.setState({
          User: {
            displayName: user.displayName
          }
        });
      } else {
        // No user is signed in.
        browserHistory.push('/signin');
      }
    });
  }

一切正常,除非我退出(并返回/登录)并使用脸书或谷歌再次登录。然后我收到一个错误说:

  

警告:setState(...):只能更新已安装或已安装   成分

我怀疑现在已卸载的先前登录状态应用程序中的onAuthStateChanged侦听器仍在运行。

有没有办法在卸载App组件时删除onAuthStateChanged侦听器?

4 个答案:

答案 0 :(得分:17)

您设置的所有听众也需要拆除。

你的怀疑非常多。

您应该使用componentWillUnmount生命周期方法删除可能污染您的应用的任何剩余侦听器。

要清理听众,请参阅以下相关代码:

authListener函数中,您需要在组件内部保存对侦听器的引用(由于调用firebase.auth().onAuthStateChanged而将其返回给您)。它将是一个钩子,它将取消引用侦听器并将其删除。

所以不要只是调用它,而是保存返回的值

this.fireBaseListener = firebase.auth().onAuthStateChanged ...

当您的组件卸载时,请使用以下代码:

componentWillUnmount() {
   this.fireBaseListener && this.fireBaseListener();
   this.authListener = undefined;
}

答案 1 :(得分:14)

我知道我迟到了,但这是一个基于钩子的解决方案:

React.useEffect(() => {
    const unsubscribe = firebase.auth().onAuthStateChanged((user) => { // detaching the listener
        if (user) {
            // ...your code to handle authenticated users. 
        } else {
            // No user is signed in...code to handle unauthenticated users. 
        }
    });
    return () => unsubscribe(); // unsubscribing from the listener when the component is unmounting. 
}, []);

答案 2 :(得分:2)

@Justin因为onAuthStateChanged返回功能所以你可以用它来清除监听器...... this.fireBaseListener = firebase.auth().onAuthStateChanged

docs:https://firebase.google.com/docs/reference/js/firebase.auth.Auth#onAuthStateChanged

  

返回包含非null数组字符串

的非null firebase.Promise

答案 3 :(得分:0)

您可以像这样检查订阅的内容,而不是检查onAuthStateChanged()内部的componentDidMount()功能。

componentWillMount() {
    //following line will help you to setState() but not required
    let set =  this  

    //this is our trick
    this.unsubscribe  = firebase.auth().onAuthStateChanged(user => {
        if (!user) {
            //navigate to guest stack
            //actually im using react-navigation
            set.props.navigation.navigate('Guest'); 
        } else {
            //set current user to state 
            set.setState({
                user: user,
                loading: false
            })
        }
    });
}

//What you have to do next is unsubscribe ;) 
componentWillUnmount() {
    this.unsubscribe();
}