【发布时间】:2021-04-12 14:50:53
【问题描述】:
我需要做一个路由器系统来区分认证用户和非认证用户。
我想要实现的是,经过身份验证的用户可以看到他们的仪表板和个人详细信息,但未经身份验证的用户只能看到登录页面、登录表单和注册表单。
我目前有上下文管理,所以我知道用户是否登录。我只需要弄清楚所有重定向和路由相关的事情。
我的代码正在制作各种“奇怪”的东西。我真的不知道我在哪里搞砸了。
AppContent.js
这是所有路由发生的地方。
AppLayout 只是一个带有页眉和页脚的布局包装器,只有在登录时才可见。
const AppContent = () => (
<Router>
<Switch>
<PublicRoute component={() => (<h1>Landing page</h1>)} path='/' exact />
<PublicRoute component={LoginPage} path='/login' exact />
<PublicRoute component={() => (<h1>Register page</h1>)} path='/register' exact />
<PrivateRoute component={Home} path='/dashboard' exact />
<PrivateRoute component={Demo} path='/demo' exact />
<PrivateRoute component={Profile} path='/profile' exact />
<PublicRoute component={() => (<h1>not found</h1>)} path='*' />
<PrivateRoute component={() => (<h1>not found</h1>)} path='*' />
</Switch>
</Router>
);
PublicRoute.js
const PublicRoute = ({ component: Component, ...rest }) => {
const { user, isLoading } = useContext(AuthContext);
if (isLoading) {
return (
<h1>Loading...</h1>
);
}
return (
<Route {...rest} render={(props) => (user ? <Redirect to='/dashboard' /> : <Component {...props} />)} />
);
};
PrivateRoute.js
const PrivateRoute = ({ component: Component, ...rest }) => {
const { user, isLoading } = useContext(AuthContext);
if (isLoading) {
return (
<h1>Loading...</h1>
);
}
return (
<Route
{...rest}
render={(props) => (user ? (
<AppLayout>
<Component {...props} />
</AppLayout>
) : <Redirect to='/login' />)}
/>
);
};
AuthStore.js
这是我管理身份验证上下文的地方。
const AuthStore = ({ children }) => {
const [token, setToken] = useState();
const [user, setUser] = useState();
const [isLoading, setIsLoading] = useState(false);
const setUserToken = async (userToken) => {
localStorage.setItem('token', userToken);
setToken(userToken);
try {
const decodedToken = jwtDecode(userToken);
const currentUserData = await AuthService.getUserData(decodedToken.username);
setUser(currentUserData);
} catch (error) {
console.log(error.name);
}
};
useEffect(() => {
setIsLoading(true);
const localToken = localStorage.getItem('token');
if (localToken) {
setUserToken(localToken);
}
setIsLoading(false);
}, []);
return (
<AuthContext.Provider value={{
user, token, setUserToken, setUser, isLoading,
}}
>
{children}
</AuthContext.Provider>
);
};
非常感谢。
编辑
我真正想要的是: 未经授权时:
- 搜索
/dashboard时,重定向到/login✅ - 搜索不存在的路线时,重定向到
/login✅ - 当搜索另一个未经授权的路线时,例如
/register,重定向到它就好了✅
授权时:
- 搜索
/login时,重定向到/dashboard✅ - 搜索不存在的路线时,重定向到 404 页面,最好是最后两条路线之一,看起来像
<PrivateRoute component={() => (<h1>not found</h1>)} path='*'✅ - 当搜索另一个授权路由时,如
/profile,重定向到它很好❌➡️它正在重新加载路由,显示登录页面,半秒后显示/dashboard,但不是/profile
【问题讨论】:
-
你能描述一下发生了什么奇怪的事情吗?我也不是 100% 确定,但我不认为 switch 将与不是路由或重定向的直接子代一起使用,你能删除布局组件并查看它是否已修复?
标签: javascript reactjs routes react-router-dom