react redux,firebas auth,在刷新useSelector时显示登录页面,如果没有用户,则直接离开



在主应用程序中,我有一个useEffect挂钩,它将检查用户是否登录:

useEffect(() => {
auth.onAuthStateChanged((user) => {
if (user) {
// User is signed in.
dispatch(
setUser({
name: user.displayName,
email: user.email,
})
);
} else {
// No user is signed in.
}
});
}, [dispatch]);

这是从我的用户缩减器setUser调用一个操作来存储用户信息。在刷新时,或者如果说我转到了Dashboard页面,我希望它在用户登录时显示该页面,如果没有登录,则re-direct显示到主页。

现在我正在更改窗口位置以进行测试,但我认为这不是正确的方式?因为它不会存储在浏览器历史记录中,是吗?不管怎么说,这是另一个问题

在加载时,用户为null,因此即使用户登录,它也在运行重定向。我该如何编写它,以等待firebase检查用户是否首先存在-我是否必须在该组件中直接使用auth state change,而不是使用选择器?我的应用程序中的其他地方也是如此?我想我可能是在写这个问题的时候自己想出来的。这是最好的方式吗?可能是一个返回用户的自定义钩子?

下面是仪表板页面:

import Section from "../components/Section/Section";
import Container from "../components/Container/Container";
import { useSelector } from "react-redux";
import { userInfo } from "../store/slices/user";
const Dashboard = () => {
const user = useSelector(userInfo);
const html = user ? (
<Section>
<Container>
<h1>Dashboard</h1>
<p>If you can see this then you are logged in</p>
</Container>
</Section>
) : (
(window.location.href = "/")
);
return html;
};
export default Dashboard;

感谢

登录挂起状态

我认为选择是好的,但你需要在你的商店有额外的信息,告诉你是否有人正在登录

在应用程序中的某个时刻,您正在调用一个登录方法,该方法是一个需要时间执行的async函数。我不确定你是否在await中得到结果。最终,auth的内部状态将发生变化,来自useEffectonAuthStateChanged回调将把用户对象dispatch发送到商店。

我建议添加一个dispatch,它在登录一开始就向您的商店发送某种PENDING_LOGIN操作。在商店的某个地方,您可以保存booleanisLoggingInenumloginState

您可以更改登录处理程序:

const handleLogin = async () => {
// immediately dispatch the pending login
dispatch({type: "PENDING_LOGIN" });
const {user} = await await auth.signInAnonymously();
// could dispatch `setUser` action from here instead of from `useEffect`, if you want to
}

Dashboard组件中,您可以从您的商店访问此新信息。

const Dashboard = () => {
const user = useSelector(userInfo);
const isLoggingIn = useSelector(someSelector);
if ( ! user && ! isLoggingIn ) {
window.location.href = "/";
}
return (
<Section>
<Container>
<h1>Dashboard</h1>
{user 
? <p>If you can see this then you are logged in</p> 
: <p>Logging in...</p>
}
</Container>
</Section>
)
};

窗口位置

更改window.location实际上会将URL添加到历史记录中。以下是MDN的一些信息。

关于将字符串值设置为window.location:

每当为location对象分配新值时,就会使用URL加载文档,就好像使用修改后的URL调用了location.assign()一样。

关于此assign()方法:

Location.assign()方法使窗口加载并显示指定URL处的文档。导航发生后,用户可以通过按"键导航回名为Location.assign()的页面;背面";按钮

如果您想导航到一个页面而不将其添加到历史记录中,则有一个单独的方法。

Location接口的replace()方法将当前资源替换为所提供URL处的资源。与assign()方法的区别在于,使用replace()后,当前页面将不会保存在会话历史记录中,这意味着用户将无法使用后退按钮导航到它

最新更新