【问题标题】:How to remove the new firebase onAuthStateChanged listener in react如何在反应中删除新的firebase onAuthStateChanged监听器
【发布时间】:2016-10-28 13:05:57
【问题描述】:

我正在使用 react-router 的 react web 应用程序中实现 firebase 身份验证。

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

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

authListener 监听 auth 变化:

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');
      }
    });
  }

一切正常,除非我退出(然后返回 /signin)并使用 facebook 或 google 再次登录。然后我收到一条错误消息:

警告:setState(...): 只能更新挂载或挂载 组件。

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

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

【问题讨论】:

    标签: reactjs firebase react-router firebase-authentication


    【解决方案1】:

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

    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】:

      您可以像这样检查订阅,而不是检查componentDidMount() 中的onAuthStateChanged() 函数。

      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();
      }
      

      【讨论】:

        【解决方案3】:

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

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

        返回非空 firebase.Promise 包含非空字符串数组

        【讨论】:

          【解决方案4】:

          您设置的任何侦听器也需要拆除。

          您的怀疑非常准确。

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

          为了清除监听器,下面是相关代码:

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

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

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

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

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

          【讨论】:

          • 知道如何删除 firebase.auth().onAuthStateChanged?旧的 firebase 有一个 .off() 函数
          • 是的,这是旧 Firebase 的一部分。新文档在这里:firebase.google.com/docs/reference/js/… 但我不知道如何使用 opt_completed ...
          • opt_completed 作为回调函数,当监听器被移除时会被调用。它用于在从 firebase 中删除侦听器时清理逻辑。
          • 用与您的用例相关的逻辑更新了我的答案。 @user2248331
          • 嗨,我想知道你能否解释一下this.fireBaseListener && this.fireBaseListener(); 的作用。谢谢
          猜你喜欢
          • 2016-09-19
          • 1970-01-01
          • 2021-05-03
          • 2019-10-29
          • 1970-01-01
          • 1970-01-01
          • 2016-01-23
          • 2014-02-17
          • 2019-02-05
          相关资源
          最近更新 更多