首页 > 解决方案 > 在没有上下文的情况下反应自定义身份验证钩子

问题描述

我在各种文章StackOverflow 答案中看到的大多数建议都建议包装自定义身份验证钩子,例如:

import { useState, useEffect } from "react"
import { auth } from "./firebaseConfig"

function useFirebaseAuthentication() => {
  const [user, setUser] = useState(null);
  useEffect(() => {
    return auth.onAuthStateChanged((user) => {
      authUser ? setUser(user) : setUser(null)
    }
  }), [])
}

进入 React 上下文。有时,该建议会附带诸如“因此您不会多次初始化 Firebase”或“如果您不这样做,onAuthStateChanged将被多次调用”之类的声明。(第一个警告来自 StackOverflow 上已删除的答案。)

但是,我不认为我上面写的钩子会受到多次 Firebase 初始化或多次调用onAuthStateChanged. 但我知道的不够多,无法确定。我所做的就是在很多控制台日志中查看正在发生的事情。具体来说,我在“服务”中定义了我的钩子并记录了所有内容:

// authService.js
import { useState, useEffect } from "react"
import { auth } from "./firebaseConfig"

// export of SignIn and SignOut components elided

export function useAuthentication() {
  const [user, setUser] = useState(null)
  useEffect(() => {
    console.log("Going to invoke onAuthStateChanged to set listener")
    const unlisten = auth.onAuthStateChanged((user) => {
      console.log("Auth hook: callback invoked")
      user ? setUser(user) : setUser(null)
    })
    return () => {
      console.log("Auth hook: unlistening")
      unlisten()
    }
  }, [])
  return user
}

然后我导入并使用了我的钩子并登录和注销了无数次并查看了日志。我没有看到任何“额外”调用——我的回调仅在身份验证状态更改时调用,实际上我的useEffect调用也仅在身份验证状态更改时调用。据我所知,没有任何东西被重新初始化或调用太频繁。

// App.js
import { useEffect, useState } from "react"
import { SignIn, SignOut, useAuthentication } from "./authService"
// importing components, stylesheets, services, etc. elided

export default function App() {
  const user = useAuthentication()    // My custom hook call
  // Other state variables elided

  useEffect(() => {
    // Database and API stuff
  }, [user])

  console.log("Rendering app")
  return (
    <div className="App">
      { /* Code using user here */ }
    </div>
  )
}

现在,我知道 react-firebase-hooks 并且知道如何使用useAuthState,我什至查看了它的源代码!我看不到那里的上下文。我正在尝试了解有关自定义挂钩的更多信息,并认为这将是一个很好的练习。然而,使用上下文似乎是常见的建议。那么我错过了什么吗?我想我担心的是,希望比我有更多 React 经验的人能回答:

我在这里做错了吗?也许我只是很幸运,因为我只在我的 App 组件中使用我的自定义钩子,而不是在其他地方?

标签: reactjsfirebaseauthenticationreact-hooks

解决方案


推荐阅读