掌握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的使用方式了,是不是很简单呢,接下来就可以开始你的业务代码了,如果本文对你有帮助,还请不要吝啬你的 👍。

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

相关推荐
y先森4 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy4 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189114 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿5 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡6 小时前
commitlint校验git提交信息
前端
虾球xz6 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇6 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒6 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员7 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐7 小时前
前端图像处理(一)
前端