使用React Hooks结合protected.route如何根据用户权限跳转对应受保护路由
实现步骤如下
1. 修复并修改Login.js代码
原有代码存在两个问题:一是提交按钮的点击事件绑定错误,页面渲染时就会直接执行提交逻辑;二是没有将用户登录状态和权限信息存入localStorage,且登录校验逻辑仅判断了管理员账号,未对普通用户账号做合法性校验。
修改后代码:
import { useState } from "react"; import { useHistory } from "react-router-dom"; const loginData = [ { id: 1, email: "mat@test.com", password: "admin123", access: "admin" }, { id: 2, email: "duo@test.com", password: "test123", access: "user" } ]; const Login = () => { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const history = useHistory(); const onSubmit = () => { // 匹配登录用户 const matchUser = loginData.find(user => user.email === email && user.password === password); if (matchUser) { // 登录成功存储用户信息到本地 localStorage.setItem("loginEmail", matchUser.email); localStorage.setItem("userAccess", matchUser.access); // 根据权限跳转对应页面 if (matchUser.access === "admin") { history.push("/"); } else { history.push("/ViewDetails"); } } else { alert("账号或密码错误"); } }; return ( <div> Login Page <br></br> <input type="text" name="email" onChange={(e) => setEmail(e.target.value)} /> <input type="password" name="password" onChange={(e) => setPassword(e.target.value)} /> {/* 用箭头函数包裹,避免渲染时直接执行 */} <input type="button" value="submit" onClick={onSubmit} /> </div> ); }; export default Login;
2. 改造ProtectedRoute.js增加权限校验
原有路由仅判断是否登录,未做权限区分,会导致普通用户也能直接访问管理员路由。改造后支持给路由配置所需权限,校验不通过时自动跳转:
import React from "react"; import { Route, Redirect } from "react-router-dom"; export const ProtectedRoute = ({ component: Component, requiredAccess, ...rest }) => { return ( <Route {...rest} render={(props) => { const loginEmail = localStorage.getItem("loginEmail"); const userAccess = localStorage.getItem("userAccess"); // 未登录跳转登录页 if (!loginEmail) { return ( <Redirect to={{ pathname: "/login", state: { from: props.location } }} /> ); } // 配置了权限要求但用户权限不匹配,跳转对应权限页面 if (requiredAccess && userAccess !== requiredAccess) { return <Redirect to={userAccess === "admin" ? "/" : "/ViewDetails"} /> } // 校验通过返回组件 return <Component {...props} />; }} /> ); };
3. 修改App.js的路由配置与导入
原有代码导入ProtectedRoute的方式错误,且需要给管理员路由增加权限配置:
import React from "react"; import "./styles.css"; import { BrowserRouter, Route, Switch } from "react-router-dom"; import Dashboard from "./components/Dashboard.js"; import Login from "./components/Login.js"; import ViewDetails from "./components/ViewDetails.js"; import UserLoginProvider from "./components/UserLoginProvider.js"; import UserProfileProvider from "./components/UserProfileProvider.js"; // 修正导入方式,因为是具名导出 import { ProtectedRoute } from "./components/protected.route.js"; import ReactDOM from "react-dom"; const App = () => { return ( <BrowserRouter> <UserLoginProvider> <UserProfileProvider> <Switch> {/* 管理员路由增加requiredAccess配置 */} <ProtectedRoute exact path="/" component={Dashboard} requiredAccess="admin" /> <ProtectedRoute path="/ViewDetails" component={ViewDetails} /> <Route path="/Login" component={Login} /> </Switch> </UserProfileProvider> </UserLoginProvider> </BrowserRouter> ); }; ReactDOM.render( React.createElement(App, null), document.getElementById("root") ); export default App;
如果需要实现用户登录后再访问登录页自动跳转到对应权限页面的逻辑,可以在Login组件的useEffect里增加判断:如果已经有登录信息,直接根据权限跳转即可。
内容的提问来源于stack exchange,提问作者soccerway
相关产品推荐
相关产品推荐

