页面刷新时 Firebase onAuthStateChange return 未定义

Firebase onAuthStateChange return undefined when page refresh

Firebase onAuthStateChange return 当我刷新页面时第一个结果未定义。因此,我无法检查用户是否已通过身份验证。

我的 useAuth 挂钩:

export default function useAuth() {
  const [authUser, setAuthUser] = useState();

  const user = useFirebase();

  useEffect(() => {
    onAuthStateChanged(user.auth, (user) => {
      user ? setAuthUser(user) : setAuthUser(false);
    });
  }, [user]);

  return authUser;
}

当我尝试刷新页面时,用户的第一个结果未定义,结束然后我得到结果。

function App() {
  const authUser = useAuth();

  console.log("au", authUser);

  return (
    <div className="App">
      <Routes>
        <Route exact path="/" element={<HomePage />} />
        <Route path="/blogs" element={<BlogsPage />} />
        <Route path="/blog/:id" element={<SingleBlogPage />} />
        <Route path="/contact" element={<ContactPage />} />
        <Route path="/login" element={<AdminLogin />} />
        <Route
          path="/admin"
          element={authUser ? <Dashboard /> : <Navigate to="/vanja-login" />}
        >
          <Route exact path="dashboard" element={<Settings />} />
        </Route>
      </Routes>
      <Footer />
    </div>
  );
}

初始 authUser 初始渲染状态未定义,因此这是预期的行为。 onAuthStateChanged 侦听器在初始渲染周期结束时通过 useEffect 实例化。如果你的 UI 的任何部分依赖于这个“不确定的” authUser 状态,它应该相应地处理它。

此外,当组件卸载或来自 firebase updates/changes 的 user 对象时,您还应该取消订阅任何身份验证状态侦听器 updates/changes。

示例:

export default function useAuth() {
  const [authUser, setAuthUser] = useState();

  const user = useFirebase();

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(
      user.auth,
      (user) => setAuthUser(user ?? false)
    );

    return unsubscribe;
  }, [user]);

  return authUser;
}

...

const AuthLayout = () => {
  const authUser = useAuth();

  console.log("au", authUser);

  if (authUser === undefined) {
    return null; // or loading spinner, etc...
  }

  return authUser ? <Outlet /> : <Navigate to="/vanja-login" />;
};

...

function App() {
  return (
    <div className="App">
      <Routes>
        <Route path="/" element={<HomePage />} />
        <Route path="/blogs" element={<BlogsPage />} />
        <Route path="/blog/:id" element={<SingleBlogPage />} />
        <Route path="/contact" element={<ContactPage />} />
        <Route path="/login" element={<AdminLogin />} />
        <Route path="/admin" element={<AuthLayout />}>
          <Route index element={<Dashboard />} />
          <Route path="dashboard" element={<Settings />} />
        </Route>
      </Routes>
      <Footer />
    </div>
  );
}