掌握React-Router-DOM最新V6版本:一文解决所有问题!

本文主要以react-router-dom v6版本为主,旧版过多概念不介绍,想必诸位应该也知道该库是做什么用的 😅,主要引领大家入门了解 react-router-dom 的使用,快速上手最新React Router v6 版本。

一、安装

首先,确保你已经安装了Node.jsnpm或yarn。然后,在项目的根目录下运行以下命令来安装react-router-dom

👉 打开你的终端并使用 Vite 引导一个新的 React 应用程序:

powershell 复制代码
#第一步执行安装命令
npm create vite@latest demo-react-vite -- --template react
# 切换到项目根目录
cd demo-react-vite
# 安装项目依赖
npm install
# 运行项目
npm run dev
# 安装react-router-dom
npm install react-router-dom

目前这里最新的版本为:

json 复制代码
"react": "^18.2.0",
"react-router-dom": "^6.22.2"

二、路由模式

React Router 支持两种路由模式:BrowserRouterHashHistory

  1. BrowserRouter 模式使用 URL 中的/来定义路由,例如:http://xxx.com/about
  2. HashHistory 模式使用 URL 中的#来定义路由,例如:http://xxx.com/#/about
  • 默认情况下,React Router 使用 BrowserRouter 作为其历史记录。 注意BrowserRouter组件最好放在最顶层所有组件之外,这样可以确保内部组件在使用 Link 做路由跳转时不会出现出错

三、路由组件

路由组件是用于处理路由的组件。在 React Router 中,路由组件通常用于显示不同的页面或视图。

3.1 创建路由组件

在项目src目录中创建一个App.jsx的文件,并在其中编写示例代码:

javascript 复制代码
import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function Home() {
	return <div>Home</div>;
}

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

3.2 Route 组件

Route组件用于定义路由规则。Route组件接收两个属性:pathelementpath属性用于定义路由的路径,element属性用于定义路由对应的组件,index属性用于指定默认子路由。

  • 注意element属性值必须写成标签的形式
  • Route组件可以嵌套使用,用于定义更复杂的路由规则。
    • 嵌套路由可以不在向旧版一样提供完整的路径,因此新版本路径书写变短,但访问路径还是需要完整路径如/about/joinus
javascript 复制代码
<Route path="/about" element={<About />}>
	<Route index element={<Address />} />
	<Route path="address" element={<Address />}></Route>
	<Route path="joinus" element={<Join />}></Route>
</Route>
  • 在新版中Route先后顺序不在重要,Router Route可以自动匹配正确的路径
  • 使用index属性可以指定默认子路由
  • 或通过 path 为空,来指定默认路由
javascript 复制代码
const router = [
	{
		path: '/home',
		element: <Home />,
		children: [
			{
				path: '',
				element: <News />,
			},
			{
				path: 'news',
				element: <About />,
			},
		],
	},
];
  • 该组件必须包含在Routes组件中

3.3 Routes 组件

Routes组件是之前版本种Switch组件的变名,抓哟用于将多个Route组件组合在一起。

LinkNavLink组件类似于 a 标签,用于创建路由链接。Link组件接收一个to属性,用于指定链接的地址,NavLink组件相似,区别是可以添加一些样式来区分当前页面。

一共两种形式,如下代码示例:

  1. 通过 style 的形式
javascript 复制代码
<NavLink
	to="/about"
	style={({ isActive }) => {
		return {
			color: isActive ? 'red' : '#000',
			fontWeight: 'bold',
		};
	}}
>
	首页
</NavLink>
  1. 通过 css 的形式
javascript 复制代码
<NavLink
	to="/about"
	className={({ isActive }) => {
		return isActive ? 'active' : '';
	}}
>
	首页
</NavLink>

Navigate组件是对旧版本的 Redirect 的替代品。

如下代码示例:

javascript 复制代码
import { Navigate } from 'react-router-dom';
<Route path="/" element={<Navigate replace to="/home" />} />;
  • 其中replace属性也可以省略,不过路由的行为由 replace 改为 push
  • replace Vs push
  • replace 替换当前 history 记录,没有历史记录
  • push 添加新的 history 记录,可以回退到上一页

3.6 Outlet 组件

Outlet组件用于在路由被匹配时,渲染匹配到的路由组件。用于占位,告诉 React Router 嵌套的内容应该显示在哪里。

如下代码示例:

javascript 复制代码
export default function App() {
	return (
		<div className="container">
			<h2>关于我们</h2>
			<ul>
				<li>
					<Link to="/about/address">公司地址</Link>
				</li>
				<li>
					<Link to="/about/join">加入我们</Link>
				</li>
			</ul>
			<div className="boxs">
				<Outlet />
			</div>
		</div>
	);
}

四、声明式路由

4.1 useRoutes 声明式的路由配置方式

在声明式路由中,不能写index, 但可以让 path: "" , 来实现显示默认组件;

如下代码示例:

javascript 复制代码
const MyRoutes = () => {
	return useRoutes([
		{
			path: '/',
			element: <Home />,
		},
		{
			path: '/home',
			element: <Home />,
		},
		{
			path: '/about',
			element: <About />,
			children: [
				{
					path: '',
					element: <Story />,
				},
				{
					path: 'address',
					element: <Address />,
				},
			],
		},
	]);
};
function App() {
	return (
		<div>
			<Router>
				<MyRoutes />
			</Router>
		</div>
	);
}
export default App;

五、编程式导航

编程式导航就是通过 JS 代码来控制路由的跳转,包括路由的跳转、路由的参数传递、路由的钩子函数等。

5.1 路由跳转useNavigate函数

useNavigate 函数用于获取路由导航的函数,该函数可以接收一个参数,表示要跳转到的路由地址。同时新版本中移除了useHistory 函数。

  • params传参方式,地址会如:/home/1。
  • search传参方式,地址会如:/home?id=1。
  • state传参方式,地址栏中不会显示

如下代码示例:

javascript 复制代码
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
navigate('/home'); // 默认是以push的形式跳转

5.1.1 push的方式

跳转到指定路由,并生成历史记录

  • 携带params参数

路由设计格式为:<Route path="about" element={<About/>} />

javascript 复制代码
navigate(`/home/${id}`);
  • 携带search参数

路由设计格式为:<Route path="about/:id/:keyword" element={<About/>} />

javascript 复制代码
navigate(`/home/${id}/${keyword}`);
  • 携带state参数

路由设计格式,以上两种方式都可以

  1. 第一种
javascript 复制代码
navigate('/home', { state: { id: '1' } });
  1. 第二种
javascript 复制代码
<NavLink
	to={`detail`}
	state={{
		id: 1,
	}}
>
	首页
</NavLink>

5.1.2 replace方式

跳转到指定路由,并替换当前历史记录

  • 携带params参数
javascript 复制代码
navigate(`/home/${id}`, { replace: true });
  • 携带search参数
javascript 复制代码
navigate(`/home/${id}/${keyword}`, { replace: true });
  • 携带state参数
javascript 复制代码
navigate('/home', { state: { id: '1' }, replace: true });

5.1.3 返回上一页

使用navigate(-1)后退到前一页,navigate(-2)后退到前两页。

5.2 获取路由参数

通过React Router提供的函数,从而获取解析地址栏中的参数。

5.2.1 useParams 函数

useParams 函数用于获取地址栏中的params参数。

如下代码示例:

javascript 复制代码
import { useParams } from 'react-router-dom';
function Home() {
	// 当前路径/home/1
	const params = useParams();
	console.log(params); // 输出:{ id: '1' }
	return <div>Home</div>;
}

5.2.2 useSearchParams 函数

useSearchParams 函数用于获取地址栏中的search参数。

其中返回的searchParams函数,具有以下方法:

  • searchParams:表示地址栏中的search参数,通过.get方法获取指定数据。
  • setSearchParams:表示设置地址栏中的search参数。
  • 在更改地址栏中的search参数时,必须传入所有的查询参数,否则会覆盖已经有的参数

如下代码示例:

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

function Home() {
	// 当前路径为/home?id=1
	const [searchParams, setSearchParams] = useSearchParams();
	console.log(searchParams.get('id')); // 输出:1
	// setSearchParams({ id: '2' }); // 设置地址栏中的search参数为id=2
	return <div>
		<h1>Home</h1>
		<button onClick={()=> setSearchParams({id:2})}>修改search参数</button>
	</div>;
}

注意 :在最新版中不能从props中获取参数,在类组件中获取参数的方法与上面一致

5.2.3 useLocation 函数

useLocation 函数用于获取地址栏中的searchparams参数。 返回的location对象,具有以下属性:

  • pathname:表示地址栏中的路径,地址如:/home?id=1。
  • search:表示地址栏中的search参数,地址如:/home/1。
  • state:表示传递的state参数,该参数不会在地址栏中展示。

如下代码示例:

javascript 复制代码
import { useLocation } from 'react-router-dom';
function Home() {
	const location = useLocation();
	console.log(location.pathname); // 输出:/home
	console.log(location.search); // 输出:?id=1&keyword=react
	console.log(location.state); // 输出:{ id: '1' }
	// 可以直接结构
	const {
		pathname,
		search,
		state: { id },
	} = useLocation();
	console.log(id); // 输出:1
	return <div>Home</div>;
}

六、路由懒加载

React中,使用import()函数来实现路由的懒加载。通过import()函数,可以异步加载路由组件,提高页面加载速度。

  1. 创建一个Suspense组件,用于包裹需要懒加载的路由组件。

  2. 使用@loadable/component库来加载路由组件。

  • 👉 安装依赖
powershell 复制代码
# npm的形式
npm install @loadable/component
# yarn的形式
yarn add @loadable/component
  • 如下代码示例
javascript 复制代码
import React from 'react';
// 导入@loadable/component,来加载路由
import loadable from '@loadable/component';

const Home = loadable(() => import('...component path'));
const About = loadable(() => import('...component path'));

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

export default App;
  • 动态路由的形式
javascript 复制代码
import React from 'react';
import { BrowserRouter, Routes, useRoutes } from 'react-router-dom';
import loadable from '@loadable/component';
// 假设动态
const menuList = [
	{
		path: '/index',
		name: '首页',
		elementPath: 'index',
	},
	{
		path: '/user',
		name: '用户管理',
		elementPath: '/user/index',
		children: [
			{
				path: '',
				name: '用户列表',
				elementPath: 'user/list',
			},
			{
				path: '/user/add',
				name: '添加用户',
				elementPath: 'user/add',
			},
		],
	},
];

function bindRouter(list) {
	let arr = [];
	list.map((item) => {
		const ComponentNode = loadable(() => import(`@/pages/${item.elementPath}`));
		if (item.children && item.children.length > 0) {
			arr.push({
				path: item.pathRoute,
				element: <ComponentNode />,
				children: [...bindRouter(item.children)],
			});
		} else {
			arr.push({
				path: item.pathRoute,
				element: <ComponentNode />,
			});
		}
	});
	return arr;
}

function App() {
	const route = bindRouter(menuList);
	const GetRoute = useRoutes(route);
	return (
		<div>
			<BrowserRouter>
				<Routes>
					<GetRoute />
				</Routes>
			</BrowserRouter>
		</div>
	);
}
export default App;

到这里相信你也已经了解了,React Router的使用方式了,是不是很简单呢,接下来就可以开始你的业务代码了,如果本文对你有帮助,还请不要吝啬你的 👍。

如有不正,欢迎大家指教,本文完~

相关推荐
贩卖纯净水.几秒前
Chrome调试工具(查看CSS属性)
前端·chrome
栈老师不回家1 小时前
Vue 计算属性和监听器
前端·javascript·vue.js
前端啊龙1 小时前
用vue3封装丶高仿element-plus里面的日期联级选择器,日期选择器
前端·javascript·vue.js
一颗松鼠1 小时前
JavaScript 闭包是什么?简单到看完就理解!
开发语言·前端·javascript·ecmascript
小远yyds1 小时前
前端Web用户 token 持久化
开发语言·前端·javascript·vue.js
吕彬-前端2 小时前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱2 小时前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai2 小时前
uniapp
前端·javascript·vue.js·uni-app
帅比九日3 小时前
【HarmonyOS Next】封装一个网络请求模块
前端·harmonyos
bysking3 小时前
【前端-组件】定义行分组的表格表单实现-bysking
前端·react.js