Raj*_*boy 207 javascript reactjs react-router-dom
我正在使用 React Router v6 并为我的应用程序创建私有路由。
在文件PrivateRoute.js中,我有代码
import React from 'react';
import {Route,Navigate} from "react-router-dom";
import {isauth} from 'auth'
function PrivateRoute({ element, path }) {
const authed = isauth() // isauth() returns true or false based on localStorage
const ele = authed === true ? element : <Navigate to="/Home" />;
return <Route path={path} element={ele} />;
}
export default PrivateRoute
Run Code Online (Sandbox Code Playgroud)
在文件route.js中我写的是:
...
<PrivateRoute exact path="/" element={<Dashboard/>}/>
<Route exact path="/home" element={<Home/>}/>
Run Code Online (Sandbox Code Playgroud)
我已经完成了相同的示例React-router Auth 示例 - StackBlitz,文件 App.tsx
我有什么遗漏的吗?
Dal*_*ney 229
我今天遇到了同样的问题,并根据Andrew Luca的这篇非常有用的文章提出了以下解决方案
在 PrivateRoute.js 中:
import React from 'react';
import { Navigate, Outlet } from 'react-router-dom';
const PrivateRoute = () => {
const auth = null; // determine if authorized, from context or however you're doing it
// If authorized, return an outlet that will render child elements
// If not, return element that will navigate to login page
return auth ? <Outlet /> : <Navigate to="/login" />;
}
Run Code Online (Sandbox Code Playgroud)
在 App.js 中(我在其他一些页面中留下了示例):
import './App.css';
import React, {Fragment} from 'react';
import {BrowserRouter as Router, Route, Routes} from 'react-router-dom';
import Navbar from './components/layout/Navbar';
import Home from './components/pages/Home';
import Register from './components/auth/Register'
import Login from './components/auth/Login';
import PrivateRoute from './components/routing/PrivateRoute';
const App = () => {
return (
<Router>
<Fragment>
<Navbar/>
<Routes>
<Route exact path='/' element={<PrivateRoute/>}>
<Route exact path='/' element={<Home/>}/>
</Route>
<Route exact path='/register' element={<Register/>}/>
<Route exact path='/login' element={<Login/>}/>
</Routes>
</Fragment>
</Router>
);
}
Run Code Online (Sandbox Code Playgroud)
在上面的路由中,这是私有路由:
<Route exact path='/' element={<PrivateRoute/>}>
<Route exact path='/' element={<Home/>}/>
</Route>
Run Code Online (Sandbox Code Playgroud)
如果授权成功,将显示该元素。否则,它将导航到登录页面。
Dre*_*ese 77
只有Route组件可以是 的子级Routes。如果您遵循 v6 文档,那么您将看到身份验证模式是使用包装器组件来处理身份验证检查和重定向。
Run Code Online (Sandbox Code Playgroud)function RequireAuth({ children }: { children: JSX.Element }) { let auth = useAuth(); let location = useLocation(); if (!auth.user) { // Redirect them to the /login page, but save the current location they were // trying to go to when they were redirected. This allows us to send them // along to that page after they login, which is a nicer user experience // than dropping them off on the home page. return <Navigate to="/login" state={{ from: location }} />; } return children; } ... <Route path="/protected" element={ <RequireAuth> <ProtectedPage /> </RequireAuth> } />
创建自定义组件的旧 v5 模式Route不再有效。使用您的代码/逻辑更新的 v6 模式可能如下所示:
const PrivateRoute = ({ children }) => {
const authed = isauth() // isauth() returns true or false based on localStorage
return authed ? children : <Navigate to="/Home" />;
}
Run Code Online (Sandbox Code Playgroud)
并使用
<Route
path="/dashboard"
element={
<PrivateRoute>
<Dashboard />
</PrivateRoute>
}
/>
Run Code Online (Sandbox Code Playgroud)
Dhe*_*ean 44
补充减少代码行数,使其更具可读性和美观性。
这可能只是一条评论,但我没有足够的观点,所以我将其作为答案。
达林的答案有效,但德鲁的答案更好!为了完成德鲁关于美学的回答,我建议创建一个私有组件,将组件作为道具而不是子组件。
私有路由文件/组件的非常基本的示例:
import { Navigate } from 'react-router-dom';
const Private = (Component) => {
const auth = false; //your logic
return auth ? <Component /> : <Navigate to="/login" />
}
Run Code Online (Sandbox Code Playgroud)
路由文件示例:
<Routes>
<Route path="/home" element={<Home />} />
<Route path="/user" element={<Private Component={User} />} />
</Routes>
Run Code Online (Sandbox Code Playgroud)
JLa*_*rky 10
我知道这并不完全是如何工作的秘诀PirvateRoute,但我只是想提一下,新文档建议使用稍微不同的方法来使用react-router v6处理这种模式:
<Route path="/protected" element={<RequireAuth><ProtectedPage /></RequireAuth>} />
Run Code Online (Sandbox Code Playgroud)
import { Navigate, useLocation } from "react-router";
export const RequireAuth: React.FC<{ children: JSX.Element }> = ({ children }) => {
let auth = useAuth();
let location = useLocation();
if (!auth.user) {
return <Navigate to="/login" state={{ from: location }} />;
}
return children;
};
Run Code Online (Sandbox Code Playgroud)
ProtectedPage如果需要,您应该在其内部添加更多路由。
有关更多详细信息,请参阅文档和示例。另外,请查看Michael Jackson 的这篇注释,其中介绍了一些实现细节。
现在是 2022 年,我做了如下的事情:
// routes.tsx
import { lazy } from "react";
import { Routes, Route } from "react-router-dom";
import Private from "./Private";
import Public from "./Public";
const Home = lazy(() => import("../pages/Home/Home"));
const Signin = lazy(() => import("../pages/Signin/Signin"));
export const Router = () => {
return (
<Routes>
<Route path="/" element={Private(<Home />)} />
<Route path="/signin" element={Public(<Signin />)} />
</Routes>
);
};
Run Code Online (Sandbox Code Playgroud)
// Private.tsx
import { Navigate } from "react-router-dom";
import { useEffect, useState } from "react";
function render(c: JSX.Element) {
return c;
}
const Private = (Component: JSX.Element) => {
const [hasSession, setHasSession] = useState<boolean>(false);
useEffect(() => {
(async function () {
const sessionStatus = await checkLoginSession();
setHasSession(Boolean(sessionStatus));
})();
}, [hasSession, Component]);
return hasSession ? render(Component) : <Navigate to="signin" />;
};
export default Private;
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
236776 次 |
| 最近记录: |