React Router v6教程

0.前端路由

前端路由可以实现让用户点击链接或输入 URL时,加载不同的视图或页面。并且仍然保持在同一个网站中,不需要重新加载整个页面。这提供了更流畅和响应迅速的用户体验。

因此可以将前端路由理解为一个工具,它可以在单一页面应用中导航到不同的视图,并且不会进行整体页面的刷新

1.Router基本使用

1.安装React Router

npm install react-router-dom

2.引入并配置路由模式

在应用程序的入口文件(通常是 index.js )中,引入 React Router 组件。

可以使用 BrowserRouterHashRouter 包裹应用程序,并在其中定义路由规则。

两者区别在于

javascript 复制代码
import React 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(
  <HashRouter>
  	<App />
  </HashRouter>
);

3.路由映射配置

  • Routes是一个包裹所有Route的组件,它可以进行路由匹配。
  • Route用于路径的匹配

path属性 :设置匹配路由

element属性 :设置匹配成功后渲染的组件

xml 复制代码
<Routes>
  <Route path="/" element={<Navigate to="/home" />} />
  <Route path="/home" element={<Home />} />
  <Route path="/about" element={<About />} />
</Routes>

4.创建路由链接进行跳转

可以使用 Link 或 NavLink 组件来创建链接,这些链接将导航到不同的路由,文章后续还会提供其余跳转方法。

如下使用Link组件创建了跳转到首页以及关于页面的链接。

javascript 复制代码
export function App(props) {
  return (
    <div className="app">
        <div className="nav">
          <Link to="/home">首页</Link>
          <Link to="/about">关于</Link>
        </div>
    </div>
  );
}
export default App;

配置成功之后点击不同的Link链接即可进行跳转(页面实际渲染内容更复杂一些,第1部分只为让读者对router使用有一个清晰的认识)

2.NavLink与Link

NavLink 和 Link 是 React Router 库中的两个组件,用于处理单页面应用程序(SPA)中的导航。

它们的主要区别在于 NavLink 在当前页面的 URL 与导航链接匹配时,会默认添加active类名。

Link 组件用于在单页面应用中进行导航。它不会添加任何额外的样式或类名到链接元素,仅仅提供了点击后进行导航的功能。在这个例子中,当用户点击链接时,应用程序会导航到 /path 路由。

javascript 复制代码
import { Link } from 'react-router-dom';

function MyComponent() {
  return (
    <div>
      <Link to="/path">点击我进行导航</Link>
    </div>
  );
}

NavLink 是 React Router 库中的一个组件,它用于在单页面应用程序中实现导航链接,并在当前路由与导航链接匹配时添加活动类名,默认会给链接添加active类名。

xml 复制代码
<div className="navlink">
  <span>NavLink组:</span>
  <NavLink to="/home">首页</NavLink>
  <NavLink to="/about">关于</NavLink>
</div>

可以看到当点击首页时,自动为首页对应的a标签添加了active

所以可以通过为active类添加CSS样式来修饰当前项。


如果担心active类名在其他地方已经用过,也可以直接为a链接添加样式属性,或者自定义类名。

首先可以直接通过为style传入函数的方式,来编写CSS样式。其中isActive是解构出的一个属性。如下案例的含义是如果被点击,就将字体颜色改为橙色。

ini 复制代码
<NavLink
  to="/home"
  style={({ isActive }) => ({ color: isActive ? "orange" : "" })}
  >
  首页
</NavLink>
  <NavLink
to="/about"
style={({ isActive }) => ({ color: isActive ? "orange" : "" })}
>
关于
  </NavLink>

通过为className传入函数的方式,来添加自定义类名。

下列案例可以实现点击某一项时,为其添加类名link-avtive

ini 复制代码
<NavLink
  to="/home"
  className={({ isActive }) => (isActive ? "link-active" : "")}
  >
  首页
</NavLink>
  <NavLink
to="/about"
className={({ isActive }) => (isActive ? "link-active" : "")}
>
关于
  </NavLink>

3.编程式导航

编程式导航指的是通过编写代码来实现页面之间的导航,而不是依赖用户的直接交互

Navigate 是一个用于执行编程式导航的组件。与 Link 或 NavLink 不同,Navigate 不是一个渲染链接的组件,而是一个用于在 React 组件内部执行导航的组件。

例如在编写Routes时,如果用户访问根路径/或者未匹配时,则将用户定向到Home组件的页面。

xml 复制代码
{/* 配置映射关系, path - Component */}
<Routes>
  {/* 重定向到 /home 路由 */}
  <Route path="/" element={<Navigate to="/home" />} />
  <Route path="/about" element={<About />} />
  <Route path="/user" element={<User />} />
  <Route path="*" element={<Navigate to="/home" />} />
</Routes>

useNavigate

在 React Router v6 中,useNavigate 是一个 React hook,用于获取导航函数,允许你在组件内部执行编程式导航。

并且这种用法的好处在于,可以为button等元素也监听导航事件,而不仅仅只用Link和NavLink进行路由跳转。

scss 复制代码
const navigate = useNavigate();
function navigateTo(path) {
  navigate(path);
}
{/* 通过useNavigate实现js代码路由跳转 */}
<button onClick={(e) => navigateTo("/category")}>分类</button>
<span onClick={(e) => navigateTo("/order")}>订单</span>

高阶组件withRouter

在函数组件中,可以直接使用 useNavigate hook,但在类组件中,hook 是无法直接使用的。这时,你可以通过高阶组件useNavigate 引入到类组件中。

首先编写高阶组件,我们将 useNavigate生成的导航函数作为 router 属性传递给需要使用hook函数的类组件。

javascript 复制代码
// 高阶组件 withRouter: 用于在类组件中使用react-router的hook函数
import { useNavigate, useParams, useLocation, useSearchParams } from "react-router-dom"
function withRouter(WrapperComponent) {
    return function(props) {
        const navigate = useNavigate()
        // 包装要传递给原始组件的参数
        const router = { navigate }
        return <WrapperComponent {...props} router={router} />
    }
}

export default withRouter

将类组件应用高阶组件withRouter后,就可以在类组件中通过 this.props.router.navigate 来执行编程式导航。

javascript 复制代码
navigateTo(path) {
  const { navigate } = this.props.router;
  navigate(path);
}


<button onClick={(e) => this.navigateTo("/home/songmenu")}>
  歌单
</button>

4.路由参数传递

动态路由

动态路由用于处理可变的URL路径,如用户个人资料页,其中URL的某些部分是动态的。如下面例子,需要根据不同的用户userId,加载不同的页面

arduino 复制代码
https://zh.weihy.org/users/{userId}

这种情况可以在路由配置中,使用元素的path属性来定义动态路由。动态部分通常用冒号(:)开头,后跟参数名称

:userId是一个动态参数,它将匹配URL中的实际用户ID。但无论访问/users/123还是/users/124,都匹配到User组件。

ini 复制代码
<Route path="/users/:userId" element={<User/>} />

接下来讨论如何获取路由参数,useParams 是 React Router 库中提供的一个 hook,用于在函数组件中获取路由参数。当路由包含动态路径参数(例如 /users/:id),你可以使用 useParams 来提取这些参数的值。以下是 useParams 的基本用法:

javascript 复制代码
import React, { memo } from "react";
import { useParams } from "react-router-dom";

const Users = memo(() => {
  const params = useParams();
  console.log("params", params);
  return (
    <div>
      <h2>id: {params.id}</h2>
    </div>
  );
});

export default Users;

当输入路径/users/133时,会log以下信息,并进行页面渲染,得到具体的动态路由参数id

查询字符串

查询字符串(Query String)是一个包含在 URL 中的一组键值对(key-value pairs),用于向服务器传递参数。查询字符串通常出现在 URL 的问号 ?之后,多个键值对之间使用 & 分隔。例如,在以下的 URL 中:

ini 复制代码
https://example.com/userpage?name=John&age=30

查询字符串是 name=John&age=30。在这个查询字符串中,name 是键,John 是对应的值;age 是另一个键,30 是它的值。

查询字符串常用于网页的 GET 请求,通过将参数附加到 URL 中,将这些参数传递给服务器。

通常使用React提供的hook useSearchParams来处理查询字符串


useSearchParams 是 React Router 库提供的一个 hook,用于获取和修改查询字符串参数。

如果在浏览器输入url:http://localhost:3000/#/userinfo/?id=3&name='麦子'

那么就会获取到查询字符串中的具体参数并进行展示。

同时可以通过Object.fromEntries来将searchParams转换为一个普通的对象,其中包含查询参数:

javascript 复制代码
import React, { memo } from "react";
import { useSearchParams } from "react-router-dom";

const UserInfo = memo(() => {
  const [searchParams] = useSearchParams();
  const id = searchParams.get("id");
  const name = searchParams.get("name");
  console.log("searchParams", searchParams);
  const queryObj = Object.fromEntries(searchParams);
  console.log("queryObj", queryObj);
  return (
    <div>
      <h2>
        用户信息 id:{id} | name:{name}
      </h2>
    </div>
  );
});

export default UserInfo;

5.路由配置

useRoutes 允许以JavaScript 对象的形式配置路由,而不是通过声明式的 JSX。该JS对象具有与Routes 元素相同的属性。

1.创建路由配置对象

配置对象的写法与编写Route元素的方式类似,只是将对应的path以及element属性换了一种编写方式,改写成为js对象的方式。

JSX方式编写路由配置

并且注意,路由配置也支持嵌套路由的写法。

javascript 复制代码
const routes = [
  {
    path: "/",
    element: <Navigate to="/home"/>
  },
  {
    path: "/home",
    element: <Home/>,
    children: [
      {
        path: "/home",
        element: <Navigate to="/home/recommend" />
      },
      {
        path: "/home/recommend",
        element: <HomeRecommends/>
      },
    ]
  },
  {
    path: "/about",
    element: <About/>
  },
  {
    path: "/category",
    element: <Category/>
  },
]

export default routes

2.应用useRoutes

调用 useRoutes 函数并传入你的路由配置对象

javascript 复制代码
import React from "react";
import { useRoutes } from "react-router-dom";
import routes from "./router";
export function App(props) {
  return (
    <div className="content">
      {useRoutes(routes)}
    </div>
  );
}
export default App;

6.路由懒加载

懒加载是一种技术,它使得应用程序在需要时才加载特定的组件,而不是在初始加载时一次性加载所有内容。通过结合使用 React.lazySuspense 实现。

1.创建懒加载的组件

React.lazy 的基本思想是将组件的加载推迟到真正需要渲染该组件的时候。

React.lazy 返回一个新的动态引入(dynamic import)的组件,这个组件会在需要时加载。

javascript 复制代码
// 演示懒加载
const About = React.lazy(() => import("../pages/About"))
const User = React.lazy(() => import("../pages/User"))

2.使用Suspense包裹App组件

  • Suspense 主要用于处理组件的懒加载和异步数据的加载
  • fallback 属性是在等待组件或数据加载完成时显示的内容。
javascript 复制代码
import { Suspense } from 'react';

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

执行npm run build,可以发现打包后确实会有多个js文件

相关推荐
理想不理想v9 分钟前
使用JS实现文件流转换excel?
java·前端·javascript·css·vue.js·spring·面试
惜.己29 分钟前
Jmeter中的配置原件(四)
java·前端·功能测试·jmeter·1024程序员节
EasyNTS30 分钟前
无插件H5播放器EasyPlayer.js网页web无插件播放器vue和react详细介绍
前端·javascript·vue.js
老码沉思录34 分钟前
React Native 全栈开发实战班 - 数据管理与状态之Zustand应用
javascript·react native·react.js
老码沉思录39 分钟前
React Native 全栈开发实战班 :数据管理与状态之React Hooks 基础
javascript·react native·react.js
guokanglun1 小时前
Vue.js动态组件使用
前端·javascript·vue.js
Go4doom1 小时前
vue-cli3+qiankun迁移至rsbuild
前端
-seventy-1 小时前
Ajax 与 Vue 框架应用点——随笔谈
前端
我认不到你1 小时前
antd proFromSelect 懒加载+模糊查询
前端·javascript·react.js·typescript
集成显卡1 小时前
axios平替!用浏览器自带的fetch处理AJAX(兼容表单/JSON/文件上传)
前端·ajax·json