🔐 React Router v6 中的私有路由
如今 WEB 领域瞬息万变,react-router
v6 已经进入测试阶段,即将面世。🤔
这仅用于学习目的,react-router v6 仍处于测试阶段,使用风险自负
v5 及以下版本中的私有路由是使用自定义组件以特定方式完成的,PrivateRoute
该组件大多名为,大多数时候只是基本组件的包装和组合Route
,Redirect
例如
function PrivateRoute(props) {
let { component: Component, children, render, ...rest } = props
let auth = useAuth();
return (
<Route
{...rest}
render={() => auth
? <Component />
: <Redirect to="/login" />
}
/>
);
}
function App() {
return (
<BrowserRouter>
<Route path="/" component={Public} />
<PrivateRoute path="/private" component={Private} />
</BrowserRouter>
);
}
但是看一下 v6 文档,似乎情况发生了一些变化,我们需要对此进行一些不同的思考。
有关所有 API 参考的信息,请参阅链接
我们继续吧。
我们过去创造的一些东西PrivateRoute
已经发生了一些变化
在 v6 中,路线以这样的方式呈现
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Public />} />
<Route path="/private" element={<Private />} />
</Routes>
</BrowserRouter>
);
}
const Public = () => <div>public</div>;
const Private = () => <div>private</div>;
所以如你所见,不再需要 render props 或 component props。
你需要传递一个直接的 JSX 元素(即使传递了也不用担心性能问题)。
好的,现在让我们看一下Route
组件源代码
/**
* Declares an element that should be rendered at a certain URL path.
*
* @see https://reactrouter.com/api/Route
*/
export function Route(_props: RouteProps): React.ReactElement | null {
invariant(
false,
`A <Route> is only ever to be used as the child of <Routes> element, ` +
`never rendered directly. Please wrap your <Route> in a <Routes>.`
);
}
等一下,代码在哪儿?👀 嗯,实际上,父组件Routes
只会使用 来Route
作为 props 和 children 的宿主,而不会对 做任何其他事情。Route
有关
Routes
实施的更多信息,请参见链接
那么我们PrivateRoute
现在该如何实现呢?🤔 如果我们对 props 进行一些调整PrivateRoute
,它看起来会像这样
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Public />} />
<PrivateRoute path="/private" element={<Private />} />
</Routes>
</BrowserRouter>
);
}
但这行不通。Routes
它只会获取 propsPrivateRoute
并完全忽略其主体。甚至连里面的 console.logPrivateRoute
都不会显示。
那么我们做什么呢?🤔 我们做了一些调整PrivateRoute
function PrivateRoute({ children }) {
const auth = useAuth();
return auth ? <>{children}</> : <Navigate to="/login" />;
}
如你所见,我们将其改为Redirect
,Navigate
并且仅在用户通过身份验证时返回children
。它的用法也略有变化
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Public />} />
<Route
path="/private"
element={
<PrivateRoute>
<Private />
</PrivateRoute>
}
/>
</Routes>
</BrowserRouter>
);
}
正如您所见,PrivateRoute
也移动到了element
道具。
的实现
PrivateRoute
可以通过多种方式完成。
PrivateRoute
这是使用的不同实现Outlet
function PrivateOutlet() {
const auth = useAuth();
return auth ? <Outlet /> : <Navigate to="/login" />;
}
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/private-outlet" element={<PrivateOutlet />}>
<Route element={<Private />} />
</Route>
</Routes>
</BrowserRouter>
);
}
这样做的好处是,您可以在同一路线下放置多个私有子路线。
完整示例请见Codesandbox
今天就到这里。祝你编程愉快!🎉 🎊 ✨
保证您的用户安全!
封面照片由Maxim Zhgulev在Unsplash上拍摄
文章来源:https://dev.to/iamandrewluca/private-route-in-react-router-v6-lg5