条件路由在 React Router 中不起作用
Conditional routes not working in React Router
我只想在用户具有访问它们的适当角色时允许路由。我在前端和后端都进行了检查,但是在使用 Switch
时有些东西不起作用。
{localStorage.getItem("roles") && localStorage.getItem("roles").split(",").includes("CONTRIBUTOR") &&
<>
{/* Contributor Routes */}
<Route exact path="/contributor/upload" component={ContributorUploadPage}/>
<Route exact path="/contributor/edit/:rawContentId" component={ContributorEditPage}/>
<Route exact path="/contributor" component={ContributorListPage}/>
</> }
{localStorage.getItem("roles") && localStorage.getItem("roles").split(",").includes("EDITOR") &&
//{/* Editor Routes */}
<>
<Route exact path="/editor/search" component={EditorSearch}/>
<Route path="/editor/upload" component={EditorUploadPage}/>
<Route exact path="/editor/edit/:finalContentId" component={EditorEditPage}/>
<Route exact path="/editor" component={EditorListPage}/>
</>
}
{localStorage.getItem("roles") && localStorage.getItem("roles").split(",").map(item => (item === "SUB_PERVIEW" || item === "SUB_SUBSCRIPTION"
|| item === "SUB_FREE" ? true : false)) &&
<>
{/* Subscriber Routes */}
<Route exact path="/content" component={ContentPage}/>
</> }
<Route path="/404" component={NotFoundPage}/>
<Redirect to="/404"/>
如果我现在转到 /editor
,即使我没有合适的角色,我也不会被重定向到 /404
。如果我删除所有条件,则会呈现 /404
页面。
只有 Route
或 Redirect
是 Switch
组件的有效子项,React 片段正在 returned 并扰乱了路由匹配。
您可以在要有条件地渲染的每个“组”或子路线区域周围放置一个 Route
。 “技巧”是return将分组的子路由在另一个开关内进行匹配。
我还建议将角色的获取分解为实用函数,以使您的代码更DRY。
const getRoles = () => (localStorage.getItem("roles") || '').split(",");
...
<Switch>
{/* Contributor Routes */}
{getRoles().includes("CONTRIBUTOR") && (
<Route path="/contributor">
<Switch>
<Route path="/contributor/upload" component={ContributorUploadPage}/>
<Route path="/contributor/edit/:rawContentId" component={ContributorEditPage}/>
<Route path="/contributor" component={ContributorListPage}/>
</Switch>
</Route>
)}
{/* Editor Routes */}
{getRoles().includes("EDITOR") && (
<Route path="/editor">
<Switch>
<Route path="/editor/search" component={EditorSearch}/>
<Route path="/editor/upload" component={EditorUploadPage}/>
<Route path="/editor/edit/:finalContentId" component={EditorEditPage}/>
<Route path="/editor" component={EditorListPage}/>
</Switch>
</Route>
)}
{/* Subscriber Routes */}
{getRoles.some(
item => ["SUB_PERVIEW", "SUB_SUBSCRIPTION", "SUB_FREE"].includes(item)
) && (
<Route path="/content" component={ContentPage}/>
)}
<Route path="/404" component={NotFoundPage}/>
<Redirect to="/404"/>
</Switch>
您可以简单地定义一个受保护的路由组件并重用它:
import React from "react";
import { Route, Redirect } from "react-router-dom";
const isContributor = localStorage.getItem("roles") && localStorage.getItem("roles").split(",").includes("CONTRIBUTOR");
const ProtectedRoute = ({ component: Component, ...rest }) => {
return (
<Route
{...rest}
render={(props) =>
isContributor ? <Component {...props} /> : <Redirect to="/404" />
}
/>
);
};
然后按如下方式使用该路线:
<ProtectedRoute exact path="/editor" component={EditorListPage}/>
我只想在用户具有访问它们的适当角色时允许路由。我在前端和后端都进行了检查,但是在使用 Switch
时有些东西不起作用。
{localStorage.getItem("roles") && localStorage.getItem("roles").split(",").includes("CONTRIBUTOR") &&
<>
{/* Contributor Routes */}
<Route exact path="/contributor/upload" component={ContributorUploadPage}/>
<Route exact path="/contributor/edit/:rawContentId" component={ContributorEditPage}/>
<Route exact path="/contributor" component={ContributorListPage}/>
</> }
{localStorage.getItem("roles") && localStorage.getItem("roles").split(",").includes("EDITOR") &&
//{/* Editor Routes */}
<>
<Route exact path="/editor/search" component={EditorSearch}/>
<Route path="/editor/upload" component={EditorUploadPage}/>
<Route exact path="/editor/edit/:finalContentId" component={EditorEditPage}/>
<Route exact path="/editor" component={EditorListPage}/>
</>
}
{localStorage.getItem("roles") && localStorage.getItem("roles").split(",").map(item => (item === "SUB_PERVIEW" || item === "SUB_SUBSCRIPTION"
|| item === "SUB_FREE" ? true : false)) &&
<>
{/* Subscriber Routes */}
<Route exact path="/content" component={ContentPage}/>
</> }
<Route path="/404" component={NotFoundPage}/>
<Redirect to="/404"/>
如果我现在转到 /editor
,即使我没有合适的角色,我也不会被重定向到 /404
。如果我删除所有条件,则会呈现 /404
页面。
只有 Route
或 Redirect
是 Switch
组件的有效子项,React 片段正在 returned 并扰乱了路由匹配。
您可以在要有条件地渲染的每个“组”或子路线区域周围放置一个 Route
。 “技巧”是return将分组的子路由在另一个开关内进行匹配。
我还建议将角色的获取分解为实用函数,以使您的代码更DRY。
const getRoles = () => (localStorage.getItem("roles") || '').split(",");
...
<Switch>
{/* Contributor Routes */}
{getRoles().includes("CONTRIBUTOR") && (
<Route path="/contributor">
<Switch>
<Route path="/contributor/upload" component={ContributorUploadPage}/>
<Route path="/contributor/edit/:rawContentId" component={ContributorEditPage}/>
<Route path="/contributor" component={ContributorListPage}/>
</Switch>
</Route>
)}
{/* Editor Routes */}
{getRoles().includes("EDITOR") && (
<Route path="/editor">
<Switch>
<Route path="/editor/search" component={EditorSearch}/>
<Route path="/editor/upload" component={EditorUploadPage}/>
<Route path="/editor/edit/:finalContentId" component={EditorEditPage}/>
<Route path="/editor" component={EditorListPage}/>
</Switch>
</Route>
)}
{/* Subscriber Routes */}
{getRoles.some(
item => ["SUB_PERVIEW", "SUB_SUBSCRIPTION", "SUB_FREE"].includes(item)
) && (
<Route path="/content" component={ContentPage}/>
)}
<Route path="/404" component={NotFoundPage}/>
<Redirect to="/404"/>
</Switch>
您可以简单地定义一个受保护的路由组件并重用它:
import React from "react";
import { Route, Redirect } from "react-router-dom";
const isContributor = localStorage.getItem("roles") && localStorage.getItem("roles").split(",").includes("CONTRIBUTOR");
const ProtectedRoute = ({ component: Component, ...rest }) => {
return (
<Route
{...rest}
render={(props) =>
isContributor ? <Component {...props} /> : <Redirect to="/404" />
}
/>
);
};
然后按如下方式使用该路线:
<ProtectedRoute exact path="/editor" component={EditorListPage}/>