本文主要以
react-router-dom v6
版本为主,旧版过多概念不介绍,想必诸位应该也知道该库是做什么用的 😅,主要引领大家入门了解 react-router-dom 的使用,快速上手最新React Router v6 版本。
一、安装
首先,确保你已经安装了
Node.js
和npm或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 支持两种路由模式:
BrowserRouter
和HashHistory
。
BrowserRouter
模式使用 URL 中的/
来定义路由,例如:http://xxx.com/about
。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
组件接收两个属性:path
和element
。path
属性用于定义路由的路径,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
组件组合在一起。
3.4 Link、NavLink 组件
Link
和NavLink
组件类似于 a 标签,用于创建路由链接。Link
组件接收一个to
属性,用于指定链接的地址,NavLink
组件相似,区别是可以添加一些样式来区分当前页面。
一共两种形式,如下代码示例:
- 通过 style 的形式
javascript
<NavLink
to="/about"
style={({ isActive }) => {
return {
color: isActive ? 'red' : '#000',
fontWeight: 'bold',
};
}}
>
首页
</NavLink>
- 通过 css 的形式
javascript
<NavLink
to="/about"
className={({ isActive }) => {
return isActive ? 'active' : '';
}}
>
首页
</NavLink>
3.5 Navigate 组件
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
参数
路由设计格式,以上两种方式都可以
- 第一种
javascript
navigate('/home', { state: { id: '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
函数用于获取地址栏中的search
和params
参数。 返回的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()
函数,可以异步加载路由组件,提高页面加载速度。
-
创建一个
Suspense
组件,用于包裹需要懒加载的路由组件。 -
使用
@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
的使用方式了,是不是很简单呢,接下来就可以开始你的业务代码了,如果本文对你有帮助,还请不要吝啬你的 👍。
如有不正,欢迎大家指教,本文完~