【问题标题】:Firebase auth and React Hook - returning function from hook not workingFirebase auth 和 React Hook - 从钩子返回函数不起作用
【发布时间】:2021-09-30 07:11:44
【问题描述】:

我有一个自定义身份验证挂钩,旨在提供用户和加载状态,以及一些基于用户的操作(例如退出)。这是我的代码:

type UserActions = {
  signOut(): Promise<void>;
};

const useUser = (): [
  firebase.User | undefined | null,
  UserActions,
  boolean,
  firebase.auth.Error | undefined
] => {
  const auth = firebase.auth();
  const [firebaseUser, loading, error] = useAuthState(auth);

  return [firebaseUser, { signOut: firebase.auth().signOut }, loading, error];
};

export default useUser;

当我在调用钩子后在另一个文件中使用signOut() 函数时,我收到错误Unhandled Rejection (TypeError): Cannot read property 'then' of undefined

但是,当我简单地将我的钩子改成这样时:

type UserActions = {
  signOut(): Promise<void>;
};

const useUser = (): [
  firebase.User | undefined | null,
  UserActions,
  boolean,
  firebase.auth.Error | undefined
] => {
  const auth = firebase.auth();
  const [firebaseUser, loading, error] = useAuthState(auth);

  const signOut = () => {
    return firebase.auth().signOut();
  };
  return [firebaseUser, { signOut }, loading, error];
};

export default useUser;

效果很好。这两种情况有什么区别?不确定我是否遗漏了有关箭头功能如何工作的内容,或者可能是打字方面的内容?

谢谢!

【问题讨论】:

    标签: reactjs firebase firebase-authentication react-hooks arrow-functions


    【解决方案1】:

    这是因为您更改了implementation of signOut() 所需的this 的上下文(为简洁起见,删除了cmets):

    fireauth.Auth.prototype.signOut = function() {
      var self = this;
      var p = this.redirectStateIsReady_.then(function() {
        if (self.authEventManager_) {
          self.authEventManager_.clearRedirectResult();
        }
        
        /* ... */
      }
      
      return this.registerPendingPromise_(p);
    }
    

    在您的第一次尝试中,您使用:

    { signOut: firebase.auth().signOut }
    

    有效地创造:

    {
      signOut() {
        var self = this;
        var p = this.redirectStateIsReady_.then(function() {
          if (self.authEventManager_) {
            self.authEventManager_.clearRedirectResult();
          }
        
          /* ... */
        }
      
        return this.registerPendingPromise_(p);
      }
    }
    

    在该代码块中,this(和self)不再是FirebaseAuth 类的实例,而是形状为{ signOut: () =&gt; Promise&lt;void&gt; } 的对象。当您调用signOut() 时会引发错误,因为该对象上不存在redirectStateIsReady_authEventManager_ 之类的属性(它们将是undefined)。

    这个错误:

    未处理的拒绝(TypeError):无法读取未定义的属性“then”

    被抛出是因为yourObject.redirectStateIsReady_undefined,这意味着代码尝试(并且失败)调用(undefined).then()

    在您的第二次(简化)尝试中,您使用:

    const signOut = () => firebase.auth().signOut();
    

    在这种情况下,signOut 方法并没有按预期从它的 FirebaseAuth 类和函数中分离出来。这被称为“绑定”一个函数,在箭头函数使它更容易之前,这是使用:

    const obj = firebase.auth();
    const signOut = obj.signOut.bind(obj);
    

    【讨论】:

    • 谢谢,很有帮助!
    猜你喜欢
    • 2020-06-18
    • 2019-11-19
    • 2020-07-16
    • 2020-08-23
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 2022-08-17
    • 2017-12-22
    相关资源
    最近更新 更多