路由页面
<pre class="brush:php;toolbar:false;">从“react”导入 React, { useContext }; 从“./context”导入{globalC}; 从“react-router-dom”导入{路由、交换机、BrowserRouter}; 从“./About”导入关于; 从“./Dashboard”导入仪表板; 从“./Login”导入登录名; 从“./PageNotFound”导入PageNotFound; 函数路线(){ const { authLogin } = useContext(globalC); console.log("authLogin", authLogin); 返回 ( <浏览器路由器> <开关> {验证登录? ( <> <路线路径=“/仪表板”组件= {仪表板}精确/> /> <路线确切路径=“/关于”组件= {关于} /> </> ) : ( <路由路径=“/”组件={登录}精确/>> )} <路由组件={PageNotFound} /> </切换> </浏览器路由器> ); } 导出默认路由;</pre>上下文页面
从“react”导入 React, { Component, createContext }; 从“axios”导入 axios; 导出 const globalC = createContext(); 导出类 Gprov 扩展组件 { 状态={ 授权登录:空, authLogin错误:空 }; 组件DidMount() { var localData = JSON.parse(localStorage.getItem("loginDetail")); 如果(本地数据){ this.setState({ authLogin:本地数据 }); } } 登录数据 = async() => { 让有效负载= { 令牌:“ctz43XoULrgv_0p1pvq7tA”, 数据: { 名称:“名字第一”, 电子邮件:“互联网电子邮件”, 电话:“电话首页”, _重复:300 } }; 等待 axios .post(`https://app.fakejson.com/q`,有效负载) .then((res) => { if (res.status === 200) { this.setState({ authLogin:res.data }); localStorage.setItem("loginDetail", JSON.stringify(res.data)); } }) .catch((错误) => this.setState({ 授权登录错误:错误 }) ); }; 使成为() { // console.log(localStorage.getItem("loginDetail")); 返回 ({this.props.children} ); } }</pre> <p><br />></p>
P粉9680081752023-08-24 09:21:05
import { Routes, Route, Navigate } from "react-router-dom"; function App() { return ( <Routes> <Route path="/public" element={<PublicPage />} /> <Route path="/protected" element={ <RequireAuth redirectTo="/login"> <ProtectedPage /> </RequireAuth> } /> </Routes> ); } function RequireAuth({ children, redirectTo }) { let isAuthenticated = getAuth(); return isAuthenticated ? children : <Navigate to={redirectTo} />; }
链接到文档: https://gist.github.com/mjackson/d54b40a094277b7afdd6b81f51a0393f
P粉5628459412023-08-24 09:02:03
<BrowserRouter> <Switch> {authLogin ? ( <> <Route path="/dashboard" component={Dashboard} exact /> <Route exact path="/About" component={About} /> </> ) : ( <Route path="/" component={Login} exact /> )} <Route component={PageNotFound} /> </Switch> </BrowserRouter>
Switch
除了Route
和Redirect
组件之外,不处理任何其他渲染。如果您想要像这样“嵌套”,那么您需要将每个组件包装在通用路由中,但这是完全不必要的。
您的登录组件也没有处理重定向回原始访问的“主页”或私有路由。
react-router-dom
v6在版本6中,自定义路由组件已经不再受欢迎,首选方法是使用auth布局组件。
import { Navigate, Outlet } from 'react-router-dom'; const PrivateRoutes = () => { const location = useLocation(); const { authLogin } = useContext(globalC); if (authLogin === undefined) { return null; // 或者加载指示器/旋转器等 } return authLogin ? <Outlet /> : <Navigate to="/login" replace state={{ from: location }} />; }
...
<BrowserRouter> <Routes> <Route path="/" element={<PrivateRoutes />} > <Route path="dashboard" element={<Dashboard />} /> <Route path="about" element={<About />} /> </Route> <Route path="/login" element={<Login />} /> <Route path="*" element={<PageNotFound />} /> </Routes> </BrowserRouter>
或者
const routes = [ { path: "/", element: <PrivateRoutes />, children: [ { path: "dashboard", element: <Dashboard />, }, { path: "about", element: <About /> }, ], }, { path: "/login", element: <Login />, }, { path: "*", element: <PageNotFound /> }, ];
...
export default function Login() { const location = useLocation(); const navigate = useNavigate(); const { authLogin, loginData } = useContext(globalC); useEffect(() => { if (authLogin) { const { from } = location.state || { from: { pathname: "/" } }; navigate(from, { replace: true }); } }, [authLogin, location, navigate]); return ( <div style={{ height: "100vh" }} className="d-flex justify-content-center align-items-center" > <button type="button" onClick={loginData} className="btn btn-primary"> 登录 </button> </div> ); }
react-router-dom
v5创建一个消费您的auth上下文的PrivateRoute
组件。
const PrivateRoute = (props) => { const location = useLocation(); const { authLogin } = useContext(globalC); if (authLogin === undefined) { return null; // 或者加载指示器/旋转器等 } return authLogin ? ( <Route {...props} /> ) : ( <Redirect to={{ pathname: "/login", state: { from: location } }} /> ); };
更新您的Login
组件以处理重定向回原始访问的路由。
export default function Login() { const location = useLocation(); const history = useHistory(); const { authLogin, loginData } = useContext(globalC); useEffect(() => { if (authLogin) { const { from } = location.state || { from: { pathname: "/" } }; history.replace(from); } }, [authLogin, history, location]); return ( <div style={{ height: "100vh" }} className="d-flex justify-content-center align-items-center" > <button type="button" onClick={loginData} className="btn btn-primary"> 登录 </button> </div> ); }
将所有路由呈现为“平面列表”
function Routes() { return ( <BrowserRouter> <Switch> <PrivateRoute path="/dashboard" component={Dashboard} /> <PrivateRoute path="/About" component={About} /> <Route path="/login" component={Login} /> <Route component={PageNotFound} /> </Switch> </BrowserRouter> ); }