🔐 React Router v6 中的私有路由
如今网络世界瞬息万变,react-routerv6 版本已经进入测试阶段,即将发布。🤔
这仅供学习之用,react-router v6 仍处于测试阶段,使用风险自负。
在 v5 及更低版本中,私有路由的实现方式比较特殊,通常使用一个名为 `<private>` 的自定义组件,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>;
如您所见,不再需要渲染属性或组件属性。
您需要直接传递一个 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 和子组件的容器,不会对它做任何其他操作。Route
有关
Routes实施方面的更多信息,请参见链接。
那么我们现在该如何实现呢PrivateRoute?🤔 如果我们对属性进行一些调整PrivateRoute,它看起来会像这样
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Public />} />
<PrivateRoute path="/private" element={<Private />} />
</Routes>
</BrowserRouter>
);
}
但这样做行不通。Routes它只会获取 propsPrivateRoute并完全忽略其主体。即使内部的 console.log 也PrivateRoute不会显示。
所以我们该怎么办?🤔 我们再做一些调整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/paramount3545/private-route-in-react-router-v6-lg5

