每个页面都经过一个AuthGuard
组件,该组件决定是否可以显示子组件,或者是否需要将用户重定向到另一个页面。
当第一次访问一个页面时,它工作得很好,但是我注意到当返回到前一个页面时有一些奇怪的行为。例如:
1.我没有登录并转到/home
,它只显示给登录的用户。我被重定向到/login
,这是正确的。
1.我点击浏览器(左上角)进入前一页。请注意,我不是通过点击网站上的链接进入前一页的。
1.在不到一秒钟的时间里,我可以看到/home
的内容,然后我被重定向回/login
,这是由AuthGuard
处理的。
我使用了一个boolean状态钩子来显示子对象,并注意到当返回到前一页时,它仍然设置为true
。true
仍然是加载/login
时获得的旧值。为什么它不重新启动?
下面是我的AuthGuard
:
const AuthGuard = ({ children, restriction }) => {
const [canShowChildren, setCanShowChildren] = useState<boolean>(false);
const { user, loading } = useAuth();
const router = useRouter();
// I need to use useEffect & async because some user data can only be retrieved
// asynchronously, though I haven't included that part here because it's
// irrelevant to the problem.
useEffect(() => {
(async () => {
if (loading || !router.isReady) return;
if (restriction === "public") {
setCanShowChildren(true);
return;
}
if (!user) {
router.push("/login");
return;
}
...
})();
}, [loading, restriction, router, user]);
if (loading || !router.isReady) {
return <Loading />;
}
return canShowChildren ? children : <Loading />;
}
我通过getStaticProps
在页面中设置了限制,如:
export async function getStaticProps() {
return {
props: {
restriction: "public",
},
};
}
2条答案
按热度按时间p4rjhz4m1#
一个简单的解决方案可以实现这一点,方法是观察路由的useEffect,并在路由改变时清除或重置状态
从“next/router”导入{useRouter}
const Page =(props)=〉{
const [state,setState] = useState(someState)
const pageRoute = useRouter().asPath
useEffect(()=〉{ setState(resetState)//当页面路由改变时状态会重置。},[pageRoute])
1yjd4xko2#
我也可以通过在状态钩子中保存路由来让它工作。但是,我认为这是一个肮脏的修复,并希望更多地了解为什么会发生这种情况摆在首位。