Firebase auth 和 React Hook - 从钩子返回函数不起作用

Posted

技术标签:

【中文标题】Firebase auth 和 React Hook - 从钩子返回函数不起作用【英文标题】:Firebase auth and React Hook - returning function from hook not working 【发布时间】: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;

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

谢谢!

【问题讨论】:

【参考方案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);

【讨论】:

谢谢,很有帮助!

以上是关于Firebase auth 和 React Hook - 从钩子返回函数不起作用的主要内容,如果未能解决你的问题,请参考以下文章

在哪里放置 firebase.auth().onAuthStateChanged()

如何在使用 firebase/auth 和 react-native 验证他/她的电子邮件后立即登录用户而不创建整个登录页面?

React-Native Firebase Phone Auth 冻结 iPhone

与 react-redux-firebase 反应 isLoaded 是真的, isEmpty 似乎是假的,但 firebase.auth().currentUser 是 null - 可能是啥原因?

React Context + Firebase Auth 未填充 onAuthStateChanged

使用 React Firebase Hooks 和 Vite 构建失败