reactjs - 基于动态上下文值的 React Router
问题描述
我希望你一切都好。
我正在开发一个 react(typescript) 应用程序,我必须在其中处理身份验证和授权。
我正在遵循这种模式。IAuthContext(将在启动期间或用户更改其状态时加载)
export interface IAuthContext {
isAuthenticated: boolean;
isInitialized: boolean;
user: firebase.User | null;
permissions: object;
landingPage: string;
isOnBoardingCompleted: boolean;
}
路由.js
const routerConfig = [
{
key: "key_",
path: '/login',
component: Login,
isPrivate : false
},
{
key: "dashboard",
path: '/dashboard',
component: Frame,
content: AnalyticsDashBoard,
isPrivate : true
},
应用程序.tsx
return (
<BrowserRouter>
<div>
<Switch>
{routes.map((route) =>{
return (route.isPrivate ?
<PrivateRoute {...route} exact/>
:
<Route path={route.path} component={route.component} key={route.key} exact/>)
})}
</Switch>
</div>
</BrowserRouter>
);
PrivateRoute.tsx
return (
<Route
{...rest}
render={(routeProps) =>
props.context.isAuthenticated ? (
<Component {...routeProps} content={props.content}/>
) : (
<Redirect
to={{
pathname: '/login',
state: { from: routeProps.location }
}}
/>
)
}
/>
);
在 privateRoute 我可以访问角色和权限以及登录页面(如果用户在登录后没有完成注册,他必须被重定向到注册页面)。此外,我需要根据身份验证在私有路由中提供所有可能的组合,因为它只会加载一次。
我试图在私人路线上这样做
if (props.context.isAuthenticated && !props.context.isOnBoardingCompleted) {
console.log("Going to redirect here to onboard--", props.context.landingPage);
return <Route path={props.context.landingPage} component={OnBoarding}/>
}
但这不起作用,因为只有 URL 发生了变化。此外,如果用户完成了入职操作,我可能没有路由,因为所有路由器控件都已使用首次值创建。请告诉我如何处理这个问题?我需要做的就是拥有某种拦截器,在其中我根据动态上下文值路由/重定向到页面。
期望:就像上面的场景一样,有多个角色和权限,所有这些条件都应该在这里检查。
解决方案
<Route path={props.context.landingPage} component={OnBoarding}/>
应该在你的Router
组件中定义。
您可以使用嵌套的三元组,但这会导致可读性问题。
return (
<Route
{...rest}
render={routeProps =>
props.context.isAuthenticated ? (
props.context.isOnBoardingCompleted ? (
<Component {...routeProps} content={props.content} />
) : (
<Redirect
to={{
pathname: "/landing", // or "/onboard" whatever the route is
state: { from: routeProps.location }
}}
/>
)
) : (
<Redirect
to={{
pathname: "/login",
state: { from: routeProps.location }
}}
/>
)
}
/>
);
推荐阅读
- office-js - 尝试获取非常大的邮件正文时,mailbox.item.body.getAsync 调用失败
- html - 可滚动的 html顶部有溢出
- c# - 我是否应该记录异常,即使它们已经记录在他们的界面中?
- javascript - 循环遍历 jQuery 数组/将值输出到 div
- ethereum - 合同可以假装吗?
- php - Laravel 5.6 - 在日志/laravel.log ubuntu xenial 16.04 上的权限被拒绝
- eclipse - eclipse - 无法将选定的文本解析为定义的函数或成员
- java - Java 等效于 Kotlin 中的 arrayof()/listof()/setof()/mapof()
- class - 在 drupal 8 的标题区域添加自定义类
- asp.net-mvc - 使用实体属性进行数据验证