react-router的使用

前置知识

单页应用

只有一个html文件 主流的开发模式变成了通过路由进行页面切换

优势: 避免整体页面刷新 用户体验变好

缺点:前端负责事情变多了 开发的难度变大

路由的本质

概念来源于后端 : 一个路径表示匹配一个服务器资源 /a.html -> a对应的文件资源 /b.html -> b对应的文件资源

共同的思想: 一对一的关系

前端的路由: 一个路径path对应唯一的一个组件comonent 当我们访问一个path 自动把path对应的组件进行渲染

js 复制代码
const routes = [
  {
    path:'/home',
    component: Home
  },
   {
    path:'/about',
    component: About
  },
   {
    path:'/article',
    component: Article
  }
]

基础使用

需求: 准备俩个按钮,点击不同按钮切换不同组件内容的显示

实现步骤:

  1. 导入必要的路由 router 内置组件
  2. 准备俩个 React 组件
  3. 按照路由的规则进行路由配置
js 复制代码
// 引入必要的内置组件
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";

// 准备俩个路由组件

const Home = () => <div>this is home</div>;
const About = () => <div>this is about</div>;

function App() {
  return (
    <div className="App">
      {/* 按照规则配置路由 */}
      <BrowserRouter>
        <Link to="/">首页</Link>
        <Link to="/about">关于</Link>
        <Routes>
          <Route path="/" element={<Home />}></Route>
          <Route path="/about" element={<About />}></Route>
        </Routes>
      </BrowserRouter>
    </div>
  );
}

export default App;

BrowerRouter

作用: 包裹整个应用,一个 React 应用只需要使用一次

模式 实现方式 路由 url 表现
HashRouter 监听 url hash 值实现 http://localhost:3000/#/about
BrowerRouter h5 的 history.pushState API 实现 http://localhost:3000/about

作用: 用于指定导航链接,完成声明式的路由跳转 类似于 <router-link/>

html 复制代码
// 这里to属性用于指定路由地址,表示要跳转到哪里去,Link组件最终会被渲染为原生的a链接
<Link to="/path">页面一</Link>

Routes

作用: 提供一个路由出口,组件内部会存在多个内置的 Route 组件,满足条件的路由会被渲染到组件内部, 类比 router-view

html 复制代码
<Routes>
  {/* 满足条件的路由组件会渲染在这里 */}
  <Route path="/" element={<Home />}></Route>
  <Route path="/about" element={<About />}></Route>
</Routes>

Route

作用: 用于定义路由路径和渲染组件的对应关系 [element:因为 react 体系内 把组件叫做 react element]

html 复制代码
<Route path="/about" element={<About />}></Route>
// 其中path属性用来指定匹配的路径地址,element属性指定要渲染的组件,
//图中配置的意思为: 当url上访问的地址为 /about 时,当前路由发生匹配,对应的About组件渲染

编程式导航

  1. 导入一个 useNavigate 钩子函数
  2. 执行 useNavigate 函数 得到 跳转函数
  3. 在事件中执行跳转函数完成路由跳转
js 复制代码
// 导入useNavigate函数
import { useNavigate } from "react-router-dom";
const Home = () => {
  // 执行函数
  const navigate = useNavigate();
  return (
    <div>
      Home
      <button onClick={() => navigate("/about")}> 跳转关于页 </button>
      {/* 
            如果在跳转时不想添加历史记录,可以添加额外参数replace 为true
            navigate('/about', { replace: true } )
         */}
    </div>
  );
};

export default Home;

路由传参

场景:跳转路由的同时,有时候要需要传递参数

1. searchParams 传参

js 复制代码
// 传参
navigate("/about?id=1001");
// 取参
import { searchParams } from "react-router-dom";
let [params] = useSearchParams();
let id = params.get("id");

2. params 传参

js 复制代码
// 传参
navigate("/about/1001");
// 取参
import { useParams } from "react-router-dom";
let params = useParams();
let id = params.id;

嵌套路由

场景:在我们做的很多的管理后台系统中,通常我们都会设计一个 Layout 组件,在它内部实现嵌套路由

实现步骤:

  1. App.js 中定义嵌套路由声明
html 复制代码
<Routes>
  <Route path="/" element={<Layout />}>
    <Route path="board" element={<Board />} />
    <Route path="article" element={<Article />} />
  </Route>
  {/* 省略部分  */}
</Routes>
  1. Layout 组件内部通过 指定二级路由出口
js 复制代码
import { Outlet } from "react-router-dom";

const Layout = () => {
  return (
    <div>
      layout
      {/* 二级路由的path等于 一级path + 二级path  */}
      <Link to="/board">board</Link>
      <Link to="/article">article</Link>
      {/* 二级路由出口 */}
      <Outlet />
    </div>
  );
};
export default Layout;

默认二级路由

场景: 应用首次渲染完毕就需要显示的二级路由

实现步骤:

  1. 给默认二级路由标记 index 属性
  2. 把原本的路径 path 属性去掉
html 复制代码
<Routes>
  <Route path="/" element={<Layout />}>
    <Route index element={<Board />} />
    <Route path="article" element={<Article />} />
  </Route>
</Routes>

404 路由配置

场景:当 url 的路径在整个路由配置中都找不到对应的 path,使用 404 兜底组件进行渲染

1- 准备一个 NotFound 组件

js 复制代码
const NotFound = () => {
  return <div>this is NotFound</div>;
};

export default NotFound;
html 复制代码
<BrowserRouter>
  <Routes>
    <Route path="/" element={<Layout />}>
      <Route index element={<Board />} />
      <Route path="article" element={<Article />} />
    </Route>
    <Route path="*" element={<NotFound />}></Route>
  </Routes>
</BrowserRouter>

集中式路由配置

场景: 当我们需要路由权限控制点时候, 对路由数组做一些权限的筛选过滤,所谓的集中式路由配置就是用一个数组统一把所有的路由对应关系写好替换 本来的 Roues 组件

js 复制代码
import { BrowserRouter, Routes, Route, useRoutes } from "react-router-dom";
import { lazy, Suspense } from "react";
import Layout from "./pages/Layout";
import NotFound from "./pages/NotFound";
// 路由懒加载 必须搭配 Suspense 使用
const Board = lazy(() => import("./pages/Board"));
const Article = lazy(() => import("./pages/Board"));
const lazyLoad = (children): ReactNode => {
  return <Suspense fallback={<div>loading...</div>}>{children}</Suspense>;
};
// 1. 准备一个路由数组 数组中定义所有的路由对应关系
const routesList = [
  {
    path: "/",
    // 重定向
    element: <Navigate to="/home/article" />,
  },
  {
    path: "/home",
    element: <Layout />,
    children: [
      {
        element: lazyLoad(<Board />),
        index: true, // index设置为true 变成默认的二级路由
      },
      {
        path: "article",
        element: lazyLoad(<Article />),
      },
    ],
  },
  // 增加n个路由对应关系
  {
    path: "*",
    element: <NotFound />,
  },
];

// 2. 使用useRoutes方法传入routesList生成Routes组件
function WrapperRoutes() {
  let element = useRoutes(routesList);
  return element;
}

function App() {
  return (
    <div className="App">
      <BrowserRouter>
        {/* 3. 替换之前的Routes组件 */}
        <WrapperRoutes />
      </BrowserRouter>
    </div>
  );
}

export default App;
相关推荐
勘察加熊人28 分钟前
angular轮播图
前端·javascript·angular.js
勘察加熊人41 分钟前
angular新闻列表分页
前端·javascript·angular.js
勘察加熊人44 分钟前
angular贪吃蛇
前端·javascript·angular.js
Long_poem1 小时前
【自学笔记】Vue基础知识点总览-持续更新
前端·vue.js·笔记
Bunury1 小时前
flex布局自定义一行几栏,靠左对齐===grid布局
前端·javascript·html
一只专注api接口开发的技术猿2 小时前
电商API接口设计:商品、订单与支付模块的微服务拆分实践
大数据·前端·数据库·微服务·云原生·架构
爱写代码的派大星2 小时前
css实现左右切换平滑效果
前端·css
大道归简2 小时前
Web网页开发——水果忍者
前端·javascript·html
OpenTiny社区2 小时前
TinyEngine v2.2版本发布:支持页面嵌套路由,提升多层级路由管理能力&开发分支调整
前端·低代码·开源·opentiny
大猫会长2 小时前
react中,在组件内返回style标签方法
前端·react.js·前端框架