我试图创建一个基本的React与Firebase和Zustand应用程序。有一个登录页面和 Jmeter 板页面。您只能查看 Jmeter 板页面,如果您登录,否则你会被重定向到登录页面。登录后,用户被重定向到 Jmeter 板页面,显示用户的电子邮件ID。问题是,当我登录后刷新 Jmeter 板页面,尽管已登录,我被重定向到登录页面,因为在第一次呈现,用户名是空的。代码是附加的。我如何绕过这个行为?
function App() {
const userData = useUserStore((state) => state.setUser);
useEffect(() => {
const authState = onAuthStateChanged(auth, (user) => {
if (user) {
userData(user.email);
} else {
console.log("no user");
}
});
return () => {
authState();
};
}, []);
return <RouterProvider router={router} />;
}
function Dashboard() {
const username = useUserStore((state) => state.username);
return username ? (
<div>Hi, {username}</div>
) : (
<Navigate to="/login" />
);
}
2条答案
按热度按时间wbgh16ku1#
有几种方法可以解决这个问题。一种方法是使用 Jmeter 板组件中的useEffect钩子来检查用户是否在每次呈现时登录。您可以使用Firebase中的onAuthStateChanged方法来检查用户是否登录。如果用户登录,则您什么也不能做。如果用户未登录,您可以使用@reach/router库中的Navigate组件将用户重定向到登录页面。
下面是一些示例代码,说明如何实现这一点:
另一种选择是使用firebase/auth库中的useSession钩子来检查用户是否登录。该钩子将在每次呈现时自动检查用户的登录状态,并相应地更新登录状态。您可以在App组件中使用该钩子,并将登录状态作为属性向下传递到Dashboard组件。
下面是一些示例代码,说明如何实现这一点:
fjaof16o2#
是的,你是对的,给每个经过验证的路由添加useEffect钩子会导致大量的代码重复,避免这种重复的一种方法是创建一个高阶组件(HOC)来为你处理验证检查。
HOC是一个函数,它将组件作为参数,并返回具有某些附加行为的新组件。在这种情况下,您可以创建一个HOC来检查用户是否已登录,如果未登录,则将用户重定向到登录页。然后,您可以使用此HOC来 Package 任何需要验证的路由,验证检查将自动处理。
下面是一些示例代码,说明如何实现这一点:
然后,您可以像这样使用HOC:
导出默认值with Auth( Jmeter 板);
现在,任何使用withAuth HOC的路由都将受到身份验证检查的保护。这样,您就可以避免在多个地方重复相同的代码。