【前端知识】React 基础巩固(四十一)——手动路由跳转、参数传递及路由配置

news2025/2/24 18:26:51

React 基础巩固(四十一)——手动路由跳转、参数传递及路由配置

一、实现手动跳转路由

  1. 利用 useNavigate 封装一个 withRouter(hoc/with_router.js)
import { useNavigate } from "react-router-dom";
// 封装一个高阶组件
function withRouter(WrapperComponent) {
  return function (props) {
    const navigate = useNavigate();
    const router = { navigate };
    return <WrapperComponent {...props} router={router} />;
  };
}

export default withRouter;
  1. 添加到hoc/index.js文件中
import withRouter from "./with_router";
export { withRouter };
  1. 利用withRouter,拦截Home组件,实现手动跳转路由
import React, { PureComponent } from "react";
import { Link, Outlet } from "react-router-dom";
import { withRouter } from "../hoc";

export class Home extends PureComponent {
  navigateTo(path) {
    const { navigate } = this.props.router;
    navigate(path);
  }

  render() {
    return (
      <div>
        <h1>Home</h1>
        <div className="nav">
          <Link to="/home/recommend">推荐</Link>
          <Link to="/home/ranking">排行榜</Link>
          <button onClick={(e) => this.navigateTo("/home/songmenu")}>
            歌单
          </button>
        </div>
        {/* 占位组件 */}
        <Outlet />
      </div>
    );
  }
}

export default withRouter(Home);

二、路由参数传递

路由参数传递包括:1.动态路由传参;2.查询字符串传参

改造withRouter,通过useParams()useSearchParams()来接收两种参数传递:

import {
  useLocation,
  useNavigate,
  useParams,
  useSearchParams,
} from "react-router-dom";
// 封装一个高阶组件
function withRouter(WrapperComponent) {
  return function (props) {
    // 1.导航
    const navigate = useNavigate();

    // 2.动态路由参数
    const params = useParams();

    // 3.查询字符串的参数:/user?name=test&age=18
    const location = useLocation();
    const [searchParams] = useSearchParams();
    const query = Object.fromEntries(searchParams)
    console.log(query);

    const router = { navigate, params, location, query };

    return <WrapperComponent {...props} router={router} />;
  };
}

export default withRouter;

在界面中,通过params来接收(Detail.js):

import React, { PureComponent } from "react";
import { withRouter } from "../hoc";

export class Detail extends PureComponent {
  render() {
    const { router } = this.props;
    const { params } = router;

    return (
      <div>
        <h2>Detail</h2>
        <h2>id:{params.id}</h2>
      </div>
    );
  }
}

export default withRouter(Detail);

通过 query 来接收(User.jsx):

import React, { PureComponent } from "react";
import { withRouter } from "../hoc";

export class User extends PureComponent {
  render() {
    const { router } = this.props;
    const { query } = router;

    return (
      <div>
        <h1>
          用户:{query.name} - {query.age}
        </h1>
      </div>
    );
  }
}

export default withRouter(User);

三、路由配置文件

当前App.jsx文件中,包含Routes相关信息,过于臃肿,我们可以将Routes通过配置的形式进行引入。

构建router/index.js,将所有的路由配置在此处:

import Home from "../pages/Home";
import About from "../pages/About";
import Login from "../pages/Login";
import NotFound from "../pages/NotFound";
import HomeRecommend from "../pages/HomeRecommend";
import HomeRanking from "../pages/HomeRanking";
import Category from "../pages/Category";
import Order from "../pages/Order";
import HomeSangMenu from "../pages/HomeSangMenu";
import Detail from "../pages/Detail";
import User from "../pages/User";
import { Navigate } from "react-router-dom";

const routes = [
  {
    path: "/",
    element: <Navigate to="/home" />,
  },
  {
    path: "/home",
    element: <Home />,
    children: [
      {
        path: "/home",
        element: <Navigate to="/home/recommend" />,
      },
      {
        path: "/home/recommend",
        element: <HomeRecommend />,
      },
      {
        path: "/home/ranking",
        element: <HomeRanking />,
      },
      {
        path: "/home/sangmenu",
        element: <HomeSangMenu />,
      },
    ],
  },
  {
    path: "/about",
    element: <About />,
  },
  {
    path: "/login",
    element: <Login />,
  },
  {
    path: "/category",
    element: <Category />,
  },
  {
    path: "/order",
    element: <Order />,
  },
  {
    path: "/detail",
    element: <Detail />,
  },
  {
    path: "/user",
    element: <User />,
  },
  {
    path: "*",
    element: <NotFound />,
  },
];
export default routes;

改写App.jsx,通过useRoutes(routes)引入路由:

import React from "react";
import {
  Link,
  NavLink,
  useNavigate,
  useRoutes,
} from "react-router-dom";
import "./style.css";
// import Home from "./pages/Home";
// import About from "./pages/About";
// import Login from "./pages/Login";
// import NotFound from "./pages/NotFound";
// import HomeRecommend from "./pages/HomeRecommend";
// import HomeRanking from "./pages/HomeRanking";
// import Category from "./pages/Category";
// import Order from "./pages/Order";
// import HomeSangMenu from "./pages/HomeSangMenu";
// import Detail from "./pages/Detail";
// import User from "./pages/User";
import routes from "./router";

export function App(props) {
  const navigate = useNavigate();

  function navigateTo(path) {
    console.log(path);

    navigate(path);
  }

  return (
    <div className="app">
      <div className="header">
        <span>header</span>
        <div className="nav">
          <NavLink to="/home">首页</NavLink>
          <NavLink to="/about">关于</NavLink>
          <NavLink to="/login">登陆</NavLink>

          <button onClick={(e) => navigateTo("/category")}>分类</button>
          <span onClick={(e) => navigateTo("/order ")}>订单</span>

          <Link to="/user?name=test&age=18">用户</Link>
        </div>
        <hr />
      </div>
      <div className="content">
        {/* 映射关系: path => Component */}

        {/* <Routes>
          <Route path="/" element={<Navigate to="/home" />} />
          <Route path="/home" element={<Home />}>
            <Route path="/home" element={<Navigate to="/home/recommend" />} />
            <Route path="/home/recommend" element={<HomeRecommend />} />
            <Route path="/home/ranking" element={<HomeRanking />} />
            <Route path="/home/songmenu" element={<HomeSangMenu />} />
          </Route>
          <Route path="/about" element={<About />} />
          <Route path="/login" element={<Login />} />
          <Route path="/category" element={<Category />} />
          <Route path="/order" element={<Order />} />
          <Route path="/detail/:id" element={<Detail />} />
          <Route path="/user" element={<User />} />
          <Route path="*" element={<NotFound />} />
        </Routes> */}

        {useRoutes(routes)}
      </div>
      <div className="footer">Footer</div>
    </div>
  );
}

export default App;

查看运行效果,与之前保持一致:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AByH8LHr-1690721021332)(https://gitee.com/outmanm78/markdown-image/raw/master/img/202307302029353.png)]

虽然成功抽离了路由配置信息,但是目前的方式,会导致路由统一打包,没有分包处理。我们可以进行改造一下,针对部分配置进行分包处理,实现路由懒加载:

import React from "react";
import Home from "../pages/Home";
// import About from "../pages/About";
// import Login from "../pages/Login";
import NotFound from "../pages/NotFound";
import HomeRecommend from "../pages/HomeRecommend";
import HomeRanking from "../pages/HomeRanking";
import Category from "../pages/Category";
import Order from "../pages/Order";
import HomeSangMenu from "../pages/HomeSangMenu";
import Detail from "../pages/Detail";
import User from "../pages/User";
import { Navigate } from "react-router-dom";

// 通过React.lazy实现About和Login界面的路由懒加载
const About = React.lazy(() => import("../pages/About"));
const Login = React.lazy(() => import("../pages/Login"));

在src/index.js中,用Suspense对App进行包裹,实现对分包加载的等待:

import React, { Suspense } from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { HashRouter } from "react-router-dom";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <HashRouter>
      <Suspense fallback={<h3>Loading...</h3>}>
        <App />
      </Suspense>
    </HashRouter>
  </React.StrictMode>
);

查看效果,与之前保持一致,懒加载实现成功:

image-20230730204327732

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iOS--runtime

什么是Runtime runtime是由C和C、汇编实现的一套API&#xff0c;为OC语言加入了面向对象、运行时的功能运行时&#xff08;runtime&#xff09;将数据类型的确定由编译时推迟到了运行时平时编写的OC代码&#xff0c;在程序运行过程中&#xff0c;最终会转换成runtime的C语言代…

操作系统5

设备管理 I/O设备 什么是?--- 将数据Input/Output(输入/输出)计算机的外部设备。 分类: 按使用特性:人机交互类外设、存储设备、网络通信设备; 按传输速度:低速、中速、高速设备; 按信息交换的单位:块设备、字符设备。 1. 块设备和字符设备的区别? 答:块设备…

C#文件操作从入门到精通(2)——查看某个dll中有哪些函数

kernel32.dll中含有ini文件操作使用的函数&#xff0c;我们可以通过VisualStudio自带的dumpbin.exe查看dll所包含的函数&#xff0c;操作步骤如下&#xff1a; 1、找到dumpbin.exe所在的文件夹 我的电脑中安装了VisualStudio2019社区版以及VisualStudio2017Professional&…

《JeecgBoot系列》JeecgBoot(ant-design-vue)实现筛选框:支持下拉搜索+下拉多选+表字典(支持条件查询)功能

JeecgBoot(ant-design-vue)实现筛选框&#xff1a;支持下拉搜索下拉多选表字典(支持条件查询)功能 JSearchMultiSelectTag.vue源文件 一、需求介绍 在使用JeectBoot(ant-design-vue)设计表单时&#xff0c;需要实现下拉搜索下拉多选表字典(支持条件查询)。 但是系统目前有两…

【Java】零基础上手SpringBoot学习日记(day1)

前言 此帖为本人学习Springboot时的笔记&#xff0c;由于是个接触计算机一年左右的新手&#xff0c;也没有网站开发经验&#xff0c;所以有些地方的理解会比较浅显并且可能会出现错误&#xff0c;望大佬们多多包涵和指正。 Web应用开发 在我的理解中&#xff0c;Web应用的开发…

robot framework之第三方测试报告Allure

Allure 简单介绍 Allure是一个美化报告的工具。支持pytest, robot framework和junit等多种测试框架。 windows 安装allure 步骤1&#xff1a;gitlab 下载解压&#xff1a;https://github.com/allure-framework/allure2/releases 步骤2&#xff1a;进入bin目录, 点击allure.bat…

资深web前端开发工程师的工作职责表述(合集)

资深web前端开发工程师的工作职责表述1 职责 - 负责相关项目的web前端研发和优化工作 - 使用敏捷开发方法&#xff0c;完成产品或产品模块的设计和开发; - 按照编码规范编程&#xff0c;编制贯穿整个软件开发周期的文档资料; - 设计前端或后端架构&#xff0c;编写核心代码…

C语言字串函数、内存函数介绍以及模拟实现

目录 前言 本期内容介绍&#xff1a; 一、字符串函数 strlen介绍 strlen 模拟实现&#xff08;三种方式&#xff09; 方法一&#xff1a;计数器法 方法二&#xff1a;递归法&#xff08;不创建临时变量法&#xff09; 方法三&#xff1a;指针-指针 strcpy介绍 strcpy模…

国产单端口1000M以太网收发(PHY)芯片介绍

2023年将是国产以太网&#xff08;Ethernet&#xff09;传输芯片公司崛起之年&#xff0c;将涌现了一大批性能稳定&#xff0c;质量可靠的产品&#xff0c;国产网络传输芯片涵盖Ethernet PHY、Switch等中高端市场,如单&#xff08;或多&#xff09;端口千兆以太网PHY品牌&#…

小研究 - 主动式微服务细粒度弹性缩放算法研究(二)

微服务架构已成为云数据中心的基本服务架构。但目前关于微服务系统弹性缩放的研究大多是基于服务或实例级别的水平缩放&#xff0c;忽略了能够充分利用单台服务器资源的细粒度垂直缩放&#xff0c;从而导致资源浪费。为此&#xff0c;本文设计了主动式微服务细粒度弹性缩放算法…

msvcp100.dll丢失怎么修复,这三个常用的修复方法可以解决

msvcp100.dll是一个动态链接库文件&#xff0c;它是Microsoft Visual C Redistributable软件包的一部分。这个文件的作用是提供在运行C程序时所需的函数和功能。msvcp100.dll是一个非常重要的文件&#xff0c;它为我们提供了许多关键的函数和类&#xff0c;使得我们能够更高效地…

算法通关村第一关——链表经典问题之删除链表元素专题笔记

删除特定节点 题目描述 给你一个链表的头节点head和一个整数val&#xff0c;请你删除链表汇总所有满足Node.val val 的节点&#xff0c;并返回新的头节点 示例 输入&#xff1a; head [1,2,6,3,4,5,6] , val 6 输出&#xff1a;[1,2,3,4,5] 分析 在删除节点cur时&#xff…

网络编程 IO多路复用 [select版] (TCP网络聊天室)

//head.h 头文件 //TcpGrpSer.c 服务器端 //TcpGrpUsr.c 客户端 select函数 功能&#xff1a;阻塞函数&#xff0c;让内核去监测集合中的文件描述符是否准备就绪&#xff0c;若准备就绪则解除阻塞。 原型&#xff1a; #include <sys/select.…

前端试用期工作总结范文5篇

前端试用期工作总结 &#xff08;篇1&#xff09; 时间飞逝&#xff0c;转眼间&#xff0c;做为一名Web前端开发的正式员工已经有两个月之久。在这个难忘而又夸姣的 日子里&#xff0c;我深入体会到了公司的积极氛围和各个部门的巨大魅力&#xff0c;目睹了公司一步步走向成熟…

计算机中存储器的层次结构

现代的存储器体系结构是这样的&#xff1a; 越往上访问速度越快&#xff0c;更小&#xff0c;成本也越高。越往下访问速度越慢&#xff0c;更大&#xff0c;成本也越低。 在最高层&#xff08;L0&#xff09;是少量快速的CPU寄存器&#xff0c;CPU可以在一个时钟周期内访问他…

八股总结(八)SSM框架体系

文章目录 Spring基础1、Spring、SpringMVC、Mybatis与SpringBoot的区别2、Spring中常用的注解及作用 Spring IoC 、 DI、Bean3、Spring IoC是什么&#xff0c;有什么好处&#xff0c;Spring中是怎么实现的&#xff1f;4、Bean相关5、Component 和 Bean 的区别是什么&#xff1f…

基于RASC的keil电子时钟制作(瑞萨RA)(5)----驱动LED数码管

基于RASC的keil电子时钟制作5_驱动LED数码管 概述硬件准备视频教程数码管说明配置IO口数码管显示库smg.csmg.h主程序 概述 本篇文章主要介绍如何使用e2studio对瑞萨RA2E1开发板进行数码管的驱动。 硬件准备 首先需要准备一个开发板&#xff0c;这里我准备的是芯片型号R7FA2E…

管理能力提升 -《六顶思考帽》读后感

我们都听过“盲人摸象”的故事&#xff0c;每个盲人讲的都是自己的真实体验&#xff0c;都认为自己一定没错&#xff0c;但彼此争吵的很厉害。 这是一种传统思辨思维&#xff0c;它有两个特征&#xff1a; 判断和争论 &#xff1a;坚持我对&#xff0c;你错&#xff0c;从自己的…

ElasticSearch 7.x

前言 elastic表示可伸缩&#xff0c;search表示查询。所以es的核心即为查询。通常情况下&#xff0c;我们的数据可以分为三类&#xff1a;结构化数据、非结构化数据、半结构化数据。 结构化数据&#xff1a;一般会用特定的结构来组织和管理数据&#xff0c;表现为二维表结构。…

51单片机学习--按键控制流水灯模式定时器时钟

TMOD负责确定T0和T1的工作模式&#xff0c;TCON控制T0和T1的启动或停止计数&#xff0c;同时包含定时器状态 TF1&#xff1a;定时器1溢出标志 TF0&#xff1a;定时器0溢出标志 0~65535 每隔1微秒计数器1&#xff0c;总时间65535微秒&#xff0c;赋上初值64535&#xff0c;则只…