《ProtectRoute怎么用?》 前端登录拦截器!React ProtectRoute + 懒加载,从入门到会用

大家好,我是一个不小心把路由玩坏了的前端人。

今天给大家拆一拆一个超级常用、却经常被初学者绕晕的组合技能:
前端路由守卫 ProtectRoute + 懒加载

搞完这套,你就可以:

  • 限制没登录的人访问付费页
  • 实现大型项目的按需加载,不用一次性全拉页面
  • 再也不用怕后端大哥问:"你这页面谁都能看啊?"

别废话,开干!


场景:谁需要 ProtectRoute?

假设你有个电商网站,里面有个 /pay 页面。

顾客必须登录后才能访问,否则就要把人轰到登录页。

没有路由守卫时,别人只要在浏览器地址栏输入 /pay,就直接进来了,付费啥的都白搞了。

所以我们要搞个路由守卫,守卫就是拦路虎:

  • 登录了? 过关,看内容!
  • 没登录? 抱歉兄弟,给我去 /login

ProtectRoute 的灵魂

在 React + React Router 里,我们要做的事情很简单:

  • 判断当前用户有没有登录
  • 没登录就用 <Navigate /> 跳转去 /login
  • 登录了就把该看的页面原样放出来

这就是 ProtectRoute 的全部核心。


来看一眼完整的 ProtectRoute.jsx

jsx 复制代码
import {
  Navigate,
  useLocation
} from 'react-router-dom';

// 鉴权组件
const ProtectRoute = (props) => {
  const { children } = props; // 包裹的子内容
  const { pathname } = useLocation(); // 当前访问路径

  const isLogin = localStorage.getItem('isLogin') === 'true'; // 登录标记

  if (!isLogin) {
    // 没登录就跳去 login,并带上来源路径
    return <Navigate to="/login" state={{ from: pathname }} />;
  }

  // 登录了,放行!
  return children;
};

export default ProtectRoute;

有没有发现,它其实啥也不渲染,只是做判断:

  • 没登录?拦截 + 重定向。
  • 登录了?把包裹的内容(子组件)放出来。如果用户未指定跳转 /pay → 不会自动跳转,而是显示当前访问的受保护页面

登录页怎么写?

ProtectRoute 只能拦截,具体登录验证得在 /login 页面里搞定。

来看一个极简示例 Login.jsx

jsx 复制代码
import { useState } from 'react';
import {
  useNavigate,
  useLocation
} from 'react-router-dom';

const Login = () => {
  const navigate = useNavigate();
  const location = useLocation();

  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    if (username === 'admin' && password === '123456') {
      localStorage.setItem('isLogin', true);
      // 登录成功,跳回来源路径,否则去首页
      navigate(location?.state?.from || '/');
    } else {
      alert('用户名或密码错误');
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <h1>登录</h1>
      <input
        type="text"
        placeholder="用户名"
        value={username}
        onChange={(e) => setUsername(e.target.value)}
        required
      />
      <input
        type="password"
        placeholder="密码"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        required
      />
      <button type="submit">登录</button>
    </form>
  );
};

export default Login;

小点:

  • 我用 localStorage 储存登录状态,这种方式够演示用了,生产环境记得用 Token + 后端校验。
  • 登录后 navigate 跳转,带着 from ,回到刚刚被拦住的页面。
  • 这个from的调用需要用useLocation这个hooks才能执行,同时这个location.state.from已经在前面ProtectRoute代码中用state赋值了'/pay',所以这里才能直接使用这个实现
  • 同时导入useNavigate这个hooks函数,用Navigate属性跳转该页面。

ProtectRoute 怎么用?

放在 Route 上包裹就完事儿!

看这段:

jsx 复制代码
<Route path="/pay" element={
  <ProtectRoute>
    <Pay />
  </ProtectRoute>
} />

意思就是:

  • ProtectRoute 守着 /pay
  • 只有登录了,<Pay /> 才能显示。

5 再来点实用的:路由懒加载

**大型项目往往页面多,**如果一次性全加载,首屏加载要半天。

所以 React 提供了懒加载(React.lazy + Suspense):

看我改造后的 App.jsx

jsx 复制代码
import { Suspense, lazy } from 'react';
import {
  BrowserRouter as Router,
  Routes,
  Route
} from 'react-router-dom';

import Navigation from './components/Navigation';
import ProtectRoute from './pages/ProtectRoute';

// 懒加载
const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));
const Pay = lazy(() => import('./pages/Pay'));
const Login = lazy(() => import('./pages/Login'));
const NotFound = lazy(() => import('./pages/NotFound'));

function App() {
  return (
    <Router>
      <Navigation />
      <Suspense fallback={<div>页面加载中...</div>}>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
          <Route path="/login" element={<Login />} />
          <Route
            path="/pay"
            element={
              <ProtectRoute>
                <Pay />
              </ProtectRoute>
            }
          />
          <Route path="*" element={<NotFound />} />
        </Routes>
      </Suspense>
    </Router>
  );
}

export default App;

关键点:

  • lazy 是按需加载。HomeAboutPay 等页面只有真正访问时才会被请求。
  • Suspense 是个兜底,加载过程中显示 <div>页面加载中...</div>,避免用户盯着空白发呆。

完整执行流:串起来

  1. 用户访问 /pay

  2. ProtectRoute 检查登录状态:

    • 没登录:拦截,跳去 /login,带上来源 /pay
    • 登录了:正常显示 <Pay /> 页面。
  3. 用户在 /login 输入正确账号密码,localStorage 标记登录成功。

  4. 登录成功后,navigate 把用户送回来源页面 /pay,用户开心付钱。


总结一句话

这套组合就是:

  • ProtectRoute:路由守卫,没登录别想看。
  • <Navigate /> :拦截后跳转去登录。
  • localStorage:临时保存登录状态(演示用)。
  • 懒加载 React.lazy + Suspense:页面多也不怕,按需拉取,首屏更快。

🎉 写在最后

这就是一个最小可用、适合新手上手的前端路由权限保护 + 懒加载组合。

你可以直接用:

  • 做会员专区
  • 做后台管理系统
  • 做只能登录后看的页面

如果你以后要更安全一点,可以把 localStorage 换成 cookie + token,并且请求后端校验。


前端的世界很简单,做对了就像拉闸限电,做错了就是裸奔。

希望这篇小白也能看懂,如果觉得有用,记得点赞、收藏、转发,不然你的路由可能又被白嫖了哦!


有需要完整示例文件的,评论区告诉我,给你一份打包好的版本,开箱即用。

完,撒花!

相关推荐
冰敷逆向几秒前
苏宁滑块VMP深入剖析(一):解混淆篇
javascript·爬虫·安全·web
江城开朗的豌豆19 分钟前
阿里邮件下载器使用说明
前端
半兽先生23 分钟前
Web 项目地图选型指南:从 Leaflet 到 MapTalks,如何选择合适的地图引擎?
前端
小小鸟00827 分钟前
JS(ES6+)基础
javascript·es6
hssfscv43 分钟前
Javaweb 学习笔记——html+css
前端·笔记·学习
Mr.Jessy1 小时前
JavaScript高级:深浅拷贝、异常处理、防抖及节流
开发语言·前端·javascript·学习
唐叔在学习1 小时前
30s让ai编写「跳过外链中转页」的油猴脚本
前端·javascript
酸菜土狗1 小时前
🔥 纯 JS 实现 SQL 字段智能解析工具类,前端也能玩转 SQL 解析
前端
wo不是黄蓉1 小时前
脚手架步骤流程
前端