我正在使用react-router设置我的应用程序,并尝试使用<Redirect/>
设置用于身份验证的路由器。
Route
组件具有两个不同的组件,一个是private Route
,另一个是public route
。
预期结果:当auth为false时,页面应跳回到我设置为<Redirect to={"/public"} />
的公共页面
到目前为止,路由似乎工作正常,但重定向无法正常工作。
任何想法都欢迎!谢谢!
PrivateRoute
interface PrivateRouteProps {
isLogin: boolean;
privateRoutes: RouteItem[];
}
const PrivateRoute: React.FunctionComponent<PrivateRouteProps> = (
props: PrivateRouteProps
) => {
return (
<>
{props.isLogin ? (
props.privateRoutes.map(item => {
return <Route key={item.path} {...item} />;
})
) : (
<Redirect to={PUBLIC.path} />
)}
</>
);
};
PublicRoute
interface PublicProps {
publicRoutes: RouteItem[];
}
const PublicRoute: React.FC<PublicProps> = (props: PublicProps) => {
return (
<>
{props.publicRoutes.map(route => (
<Route key={route.path} {...route} />
))}
</>
);
};
Route
<BrowserRouter>
<Switch>
<PublicRoute publicRoutes={publicRoutes} />
<PrivateRoute privateRoutes={privateRoutes} isLogin={login} />
</Switch>
</BrowserRouter>
更新
正如公认的答案所述,<Switch/>
完全与Fragment配合使用,因此我按照以下方式修改了路线,它的作用就像是一种魅力。
只是更新它,以便有人可能有类似的问题。
<BrowserRouter>
<Switch>
{publicRoutes.map(item => {
return <Route key={item.path} {...item}/>
})}
{privateRoutes.map(item => {
return <PrivateRoute key={item.path}
exact={item.exact}
component={item.component}
path={item.path}
redirectPath={SIGN_IN.path}
/>
})}
</Switch>
</BrowserRouter>
答案 0 :(得分:2)
我遍历了您的代码,归结为一件事。组件<Switch>
与片段<></>
一起工作的方式。它只寻找第一个React Fragment,因为他们不想横穿一棵树:
https://github.com/ReactTraining/react-router/issues/5785
要解决此问题,您需要删除组件内部的React.Fragment。 因此您的应用程序将如下所示:
<Switch>
<Route ...>
<Route ...>
<Route ...>
</Switch>
和不(现在是 btw )
<Switch>
//it will only sees the first one //if you switch orders - Private with Public
// Private will work but not Public anymore :(
<React.Fragment>
<Route ...>
<Route ...>
</React.Fragment>
<React.Fragment>
<Route ...>
</React.Fragment>
</Switch>
另一种解决方案(这是我做的,因为我不熟悉TypeScript,不足以更改类型和返回值)是在您的switch应用程序中添加 wrapper 并处理private的返回在<Route>
内部使用render方法进行路由,如下所示:
//index.tsx
<Switch>
<>
<PublicRoute publicRoutes={publicRoutes}/>
<PrivateRoute privateRoutes={privateRoutes} isLogin={login}/>
</>
</Switch>
这会导致另一个错误,即无限循环重新渲染(同样,react-router很可能是 使用嵌套路由的时间很差),并解决了对私有路由执行以下操作组件:
//PrivateRoute.tsx
return (
<>
{props.privateRoutes.map(item =>
<Route key={item.path} exact path={item.path} render={() => (
!props.isLogin
? (
<Redirect to={PUBLIC.path}/>
):
//HOC transforming function Component into Component
// @ts-ignore (you can deal here better than me hehehe)
((PrivateComponent)=><PrivateComponent/>)(item.component)
)}/>)}
</>
);
TL,DR:您正在通过在结构内部添加<></>
(转换为 React.Fragment )来增加嵌套的复杂性。如果您删除它们或按照上面的代码操作,应该没问题
希望我对您有所帮助。祝好运! :)