React:使用高阶组件实现vue中的路由守卫功能

前言

最近在学习 react 发现react 中没有像vue 那样有官方提供的路由守卫 。

问了下 豆包元宝千问ChatGPT 给的方案五花八门,对于新手来说很头疼。结合

这几个AI助手给的方案,简单整理下比较容易理解的方案。

高阶组件

高阶组件

简单来说:

  • 它是一个纯函数(没有副作用)
  • 接收一个组件作为参数
  • 返回一个新的、增强后的组件

可以用一个通俗的比喻理解:HOC 就像一个 "组件加工厂",你把基础组件送进去,它给你返回一个添加了新功能(比如权限校验、数据请求、样式包装)的新组件。

javascript 复制代码
/**
 * 认证守卫
 * React.FC是React.FunctionComponent 的简写,表示这是一个函数组件
 * React.PropsWithChildren 表示这是一个包含子元素的props
 */
import { Navigate } from "react-router-dom";
import { loginUtil } from "../utils";
export const withAuthGuard = (
  Component: React.FC<React.PropsWithChildren>,
  requireAuth: boolean = true,
) => {
  return (props: React.PropsWithChildren) => {
    // 判断是否登录
    const isLogin = loginUtil.isLogin();
    // 需要登录但是未登录,跳转到登录界面
    if (requireAuth && !isLogin) {
      return <Navigate to="/login" replace />;
    }
    // 不需要登录但是已登录,跳转到首页
    if (!requireAuth && isLogin) {
      return <Navigate to="/home" replace />;
    }
    // 其他情况,渲染组件
    return <Component {...props} />;
  };
};
// 设置组件名称,便于调试
withAuthGuard.displayName = "withAuthGuard";

使用

javascript 复制代码
import { Button } from "antd";
import { useNavigate } from "react-router-dom";
import { withAuthGuard } from "@/hoc";

const LoginInFc = () => {
  const navigate = useNavigate();
  // 登录
  const submitLogin = () => {
    console.log("登录");
    localStorage.setItem("token", "123456");
    navigate("/home");
  };

  return (
    <div>
      <Button type="primary" onClick={submitLogin}>
        登录
      </Button>
    </div>
  );
};

const LoginIn = withAuthGuard(LoginInFc, false);

export default LoginIn;

效果

注意

要与普通的容器组件进行区分,例如

javascript 复制代码
// 1. 普通容器组件写法
const AuthWrapper = ({ children }) => {
  const isAuthenticated = checkAuth(); // 检查权限逻辑
  
  if (!isAuthenticated) {
    return <Redirect to="/login" />;
  }
  
  return children; // 这里就是"插槽"
};

// 2. 使用方式
function App() {
  return (
    <AuthWrapper>
      <Dashboard />  {/* 这就是 children */}
    </AuthWrapper>
  );
}

这其实类似与vue中的普通插槽

相关推荐
HjhIron5 分钟前
从栈到队列,再到链表:前端开发者必知的线性数据结构
前端·javascript
PedroQue995 分钟前
uni-app路由管理神器:vue-router风格体验
前端·uni-app
用户1733598075376 分钟前
花两周用 Vue 3 做了个 PDF 工具站,我在生产环境踩了 8 个坑
前端·vue.js
风骏时光牛马6 分钟前
TypeScript 泛型与工具类型实战:企业级通用数据请求封装完整案例
前端
卤蛋fg66 分钟前
使用 vxe-table 树表格实现产品列表与明细关联展示
vue.js
阿猫的故乡7 分钟前
Vue自定义指令从入门到实用:自动聚焦、权限控制、防抖、懒加载……全案例教学
前端·javascript·vue.js
嘟嘟071710 分钟前
吃透 JS 八大数据类型与内存原理,从代码到底层一站式复习
前端
问心无愧051311 分钟前
ctf show web入门157 158
前端·笔记
该用户已成仙24 分钟前
vue3 使用 vuedraggable 报错 TypeError: isFunction2 is not a function
前端·javascript·vue.js
aidou131424 分钟前
Kotlin中实现星级评价选择功能(仅支持整数)
前端·kotlin·自定义view·imageview·ontouchevent·customratingbar