react-router-dom用法

react-router-dom用法

目录

  1. 安装配置
  2. 基本路由
  3. 路由匹配
  4. 路由嵌套
  5. 路由传参
  6. 编程式导航
  7. 路由守卫
  8. 最佳实践

安装配置

# 安装
npm install react-router-dom

# TypeScript 类型支持
npm install @types/react-router-dom

基本设置

// App.tsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/users" element={<Users />} />
      </Routes>
    </BrowserRouter>
  );
}

基本路由

1. 基本路由配置

<Routes>
  {/* 首页路由 */}
  <Route path="/" element={<Home />} />
  
  {/* 普通路由 */}
  <Route path="/about" element={<About />} />
  
  {/* 404 路由 */}
  <Route path="*" element={<NotFound />} />
</Routes>

2. 路由链接

import { Link, NavLink } from 'react-router-dom';

function Navigation() {
  return (
    <nav>
      {/* 基本链接 */}
      <Link to="/">Home</Link>
      
      {/* 带激活状态的链接 */}
      <NavLink 
        to="/about"
        className={({ isActive }) => isActive ? 'active' : ''}
      >
        About
      </NavLink>
    </nav>
  );
}

路由匹配

1. 精确匹配

{/* 只匹配完全相同的路径 */}
<Route path="/users" element={<Users />} />

2. 模糊匹配

{/* 匹配以 /users 开头的所有路径 */}
<Route path="/users/*" element={<Users />} />

3. 重定向

import { Navigate } from 'react-router-dom';

{/* 基本重定向 */}
<Route path="/old-path" element={<Navigate to="/new-path" />} />

{/* 条件重定向 */}
function PrivateRoute({ children }) {
  const isAuthenticated = checkAuth();
  
  return isAuthenticated ? children : <Navigate to="/login" />;
}

路由嵌套

1. 基本嵌套

function App() {
  return (
    <Routes>
      <Route path="/" element={<Layout />}>
        {/* 嵌套路由 */}
        <Route index element={<Home />} />
        <Route path="about" element={<About />} />
        <Route path="users" element={<Users />}>
          {/* 二级路由 */}
          <Route index element={<UserList />} />
          <Route path=":id" element={<UserDetail />} />
        </Route>
      </Route>
    </Routes>
  );
}

// Layout.tsx
import { Outlet } from 'react-router-dom';

function Layout() {
  return (
    <div>
      <nav>{/* 导航内容 */}</nav>
      <main>
        <Outlet /> {/* 渲染子路由 */}
      </main>
    </div>
  );
}

路由传参

1. URL 参数

// 路由配置
<Route path="/users/:id" element={<UserDetail />} />

// 组件中获取参数
import { useParams } from 'react-router-dom';

function UserDetail() {
  const { id } = useParams();
  return <div>User ID: {id}</div>;
}

2. 查询参数

// 使用查询参数
import { useSearchParams } from 'react-router-dom';

function UserList() {
  const [searchParams, setSearchParams] = useSearchParams();
  const page = searchParams.get('page') || '1';
  
  return (
    <div>
      <p>Current Page: {page}</p>
      <button onClick={() => setSearchParams({ page: '2' })}>
        Next Page
      </button>
    </div>
  );
}

3. 状态传递

// 传递状态
<Link to="/about" state={{ from: 'home' }}>About</Link>

// 获取状态
import { useLocation } from 'react-router-dom';

function About() {
  const location = useLocation();
  const { from } = location.state || {};
  
  return <div>From: {from}</div>;
}

编程式导航

1. 使用 useNavigate

import { useNavigate } from 'react-router-dom';

function LoginButton() {
  const navigate = useNavigate();
  
  const handleLogin = async () => {
    const success = await login();
    if (success) {
      // 基本导航
      navigate('/dashboard');
      
      // 带参数导航
      navigate('/users/123');
      
      // 带状态导航
      navigate('/about', { state: { from: 'login' } });
      
      // 返回上一页
      navigate(-1);
    }
  };
  
  return <button onClick={handleLogin}>Login</button>;
}

2. 替换历史记录

// 替换当前历史记录
navigate('/new-path', { replace: true });

路由守卫

1. 基本认证守卫

function PrivateRoute({ children }) {
  const auth = useAuth(); // 自定义 hook 检查认证状态
  const navigate = useNavigate();
  
  useEffect(() => {
    if (!auth.isAuthenticated) {
      navigate('/login', { 
        replace: true,
        state: { from: location.pathname }
      });
    }
  }, [auth, navigate]);
  
  return auth.isAuthenticated ? children : null;
}

// 使用守卫
<Route
  path="/dashboard"
  element={
    <PrivateRoute>
      <Dashboard />
    </PrivateRoute>
  }
/>

2. 权限控制

function PermissionRoute({ children, requiredPermission }) {
  const { hasPermission } = usePermissions();
  
  if (!hasPermission(requiredPermission)) {
    return <Navigate to="/unauthorized" />;
  }
  
  return children;
}

最佳实践

1. 路由配置集中管理

// routes.ts
export const routes = [
  {
    path: '/',
    element: <Layout />,
    children: [
      { index: true, element: <Home /> },
      { path: 'about', element: <About /> },
      {
        path: 'users',
        element: <Users />,
        children: [
          { index: true, element: <UserList /> },
          { path: ':id', element: <UserDetail /> }
        ]
      }
    ]
  }
];

// App.tsx
import { useRoutes } from 'react-router-dom';

function App() {
  const element = useRoutes(routes);
  return element;
}

2. 懒加载路由

import { lazy, Suspense } from 'react';

const Dashboard = lazy(() => import('./pages/Dashboard'));

function App() {
  return (
    <Routes>
      <Route
        path="/dashboard"
        element={
          <Suspense fallback={<Loading />}>
            <Dashboard />
          </Suspense>
        }
      />
    </Routes>
  );
}

3. 404 处理

<Routes>
  {/* 其他路由 */}
  <Route path="*" element={<NotFound />} />
</Routes>

总结

  1. 路由类型:

    • 基本路由
    • 嵌套路由
    • 动态路由
    • 404 路由
  2. 参数传递:

    • URL 参数
    • 查询参数
    • 状态传递
  3. 导航方式:

    • 声明式(Link/NavLink)
    • 编程式(useNavigate)
  4. 最佳实践:

    • 集中配置
    • 路由懒加载
    • 路由守卫
    • 权限控制

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/947521.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CDPHudi实战-集成spark

[一]使用Spark-shell 1-配置hudi Jar包 [rootcdp73-1 ~]# for i in $(seq 1 6); do scp /opt/software/hudi-1.0.0/packaging/hudi-spark-bundle/target/hudi-spark3.4-bundle_2.12-1.0.0.jar cdp73-$i:/opt/cloudera/parcels/CDH/lib/spark3/jars/; done hudi-spark3.4-bu…

mac m2 安装 docker

文章目录 安装1.下载安装包2.在downloads中打开3.在启动台打开打开终端验证 修改国内镜像地址小结 安装 1.下载安装包 到官网下载适配的安装包&#xff1a;https://www.docker.com/products/docker-desktop/ 2.在downloads中打开 拖过去 3.在启动台打开 选择推荐设置 …

Power BI如何连接Azure Databricks数据源?

故事背景: 近期有朋友询问&#xff0c;自己公司有一些项目使用了Azure Databricks用于数据存储。如何使用Power BI Desktop桌面开发软件连接Azure Databricks的数据源呢&#xff1f; 解决方案: 其实Power BI是提供了连接Azure Databricks数据源的选项的&#xff0c;只是配置…

Python入门教程 —— 进制转换

找其他编译器&#xff0c;系统解释器&#xff0c;这样速度会快很多。 进制 现代的计算机和依赖计算机的设备里都用到二进制(即0和1)来保存和表示数据&#xff0c;一个二进制表示一个比特(Bit)。 在二进制的基础上&#xff0c;计算机还支持八进制和十六进制这两种进制。 除了…

HTML5新特性|05 CSS3边框CSS3背景

CSS3边框 1、CSS3边框: 通过CSS3&#xff0c;您能够创建圆角边框&#xff0c;向矩形添加阴影&#xff0c;使用图片来绘制边框-并且不需使用设计软件&#xff0c;比如PhotoShop。 属性: border-radius 圆角box-shadow:水平阴影 垂直阴影 阴影的清晰度 阴影的大小 阴影的颜色…

《Vue3实战教程》26:Vue3Transition

如果您有疑问&#xff0c;请观看视频教程《Vue3实战教程》

SpringCloudAlibaba实战入门之Sentinel服务降级和服务熔断(十五)

一、Sentinel概述 1、Sentinel是什么 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 一句话概括:sentinel即Hystrix的替代品,官网: https://sentinelguard.io/zh…

Scratch教学作品 | 白水急流——急流勇进,挑战反应极限! ‍♂️

今天为大家推荐一款刺激又好玩的Scratch冒险作品——《白水急流》&#xff01;由AgentFransidium制作&#xff0c;这款作品将带你体验惊险的急流救援任务&#xff0c;帮助那位“睡着的疯狂人”安全穿越湍急水域&#xff01;想要挑战自己的反应极限&#xff1f;快来试试吧&#…

计算机毕业设计Django+Tensorflow音乐推荐系统 音乐可视化 卷积神经网络CNN LSTM音乐情感分析 机器学习 深度学习 Flask

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

Nginx服务器配置SSL证书

1.执行以下命令&#xff0c;在Nginx的conf目录下创建一个用于存放证书的目录。 cd /usr/local/nginx/conf #进入Nginx默认配置文件目录。该目录为手动编译安装Nginx时的默认目录&#xff0c;如果您修改过默认安装目录或使用其他方式安装&#xff0c;请根据实际配置调整。 mkd…

Gemini和ChatGPT全面对比分析,有什么区别和优势?

当 AI 聊天机器人首次出现时&#xff0c;每个人都在竞相发布自己的足够好的第一版 AI 聊天机器人&#xff0c;很容易在 Gemini 与 ChatGPT 等应用程序之间进行比较。但随着 Google 和 OpenAI 不断添加新功能、模型和访问其聊天机器人的方式&#xff0c;差异变得不那么明显。 现…

从0到机器视觉工程师(二):封装调用静态库和动态库

目录 静态库 编写静态库 使用静态库 方案一 方案二 动态库 编写动态库 使用动态库 方案一 方案二 方案三 总结 静态库 静态库是在编译时将库的代码合并到最终可执行程序中的库。静态库的优势是在编译时将所有代码包含在程序中&#xff0c;可以使程序独立运行&…

低代码开发:开启企业数智化转型“快捷键”

一、低代码开发浪潮来袭&#xff0c;企业转型正当时 在当今数字化飞速发展的时代&#xff0c;低代码开发已如汹涌浪潮&#xff0c;席卷全球。从国际市场来看&#xff0c;诸多企业巨头纷纷布局低代码领域&#xff0c;像微软的 PowerApps、OutSystems 等平台&#xff0c;凭借强大…

UE5动画蓝图

动画蓝图&#xff0c;混合空间&#xff0c;状态机&#xff0c;瞄准偏移&#xff0c;动画蒙太奇&#xff0c;动画混合&#xff0c;骨骼绑定&#xff0c;动画重定向&#xff0c;动画通知&#xff0c;Control Rig…… 虚幻动画模块是一个庞大的系统&#xff0c;大模块里又包含很多…

[redux] useDispatch的两种用法

先重写2个方法先, 方便ts类型推导,如果你看不懂为什么这么写, 先看我这篇 [redux] ts声明useSelector和useDispatch-CSDN博客 export type RootState ReturnType<typeof store.getState>; export type AppDispatch typeof store.dispatch; export const useAppDispat…

javaEE-网络原理-1初识

目录 一.网络发展史 1.独立模式 2.网络互联 二.局域网LAN 1.基于网线直连&#xff1a; 2.基于集线器组件&#xff1a; 3.基于交换机组件&#xff1a; 4.基于交换机和路由器组件 ​编辑 三、广域网WAN 四、网络通信基础 1.ip地址 2.端口号&#xff1a; 3.协议 4.五…

jenkins入门3

1、新建视图 视图可以理解为是item的集合&#xff0c;这样可以将item分类。新建视频可以选择加入已有的item 2、新建item 1)输入任务名称、选择一个类型&#xff0c;常用的是第一个freestyle project 2&#xff09;进行item相关配置&#xff0c;general 设置项目名字,描述,参数…

【C语言的小角落】--- 深度理解取余/取模运算

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; C语言的小角落 本篇博客我们来深度理解取余/取模&#xff0c;以及它们在不同语言中出现不同现象的原因。 &#x1f3e0; 关于取整 &#x1f3b5; 向0取整…

mapbox进阶,添加路径规划控件

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️MapboxDirections 控件二、🍀添加路径规划控件1. ☘️实现思路2. ☘️…

linux-25 文件管理(三)复制、移动文件,cp,mv

命令cp是copy的简写&#xff0c;而mv则是move的简写。那既然copy是用于实现复制文件的&#xff0c;那通常一般我们要指定其要复制的是谁&#xff1f;而且复制完以后保存在什么地方&#xff0c;对吧&#xff1f;那因此它的使用格式很简单&#xff0c;那就是cp srcfile dest&…