概述
React Router 创建于 2014 年,是一个用于 React 的声明式、基于组件的客户端和服务端路由库,它可以保持 UI 与 URL 同步,拥有简单的 API 与强大的功能。
安装依赖
// npm
npm install react-router-dom@6// pnpm
pnpm add react-router-dom@6// yarn
yarn add react-router-dom@6
基本使用
前提:区分react-router和react-router-dom
react-router:这是核心库,提供了基本的路由功能。它并不包含与 DOM 相关的功能,而是专注于路由逻辑和 API。
react-router-dom:这是基于 react-router 的一个库,专门为 Web 应用提供路由功能。它包含了与浏览器 DOM 交互的组件和功能。
react-router-native:这是 React Router 的一个库,专为 React Native 应用设计。它提供了与移动设备和原生组件交互的路由功能。
路由模式
BrowserRouter
描述:最常用的路由方式,即浏览器路由。使用 HTML5 的历史 API(如 pushState 和 replaceState)来管理路由,支持干净的 URL(不包含哈希)。适合单页面应用(SPA),需要 URL 结构友好的情况下。
使用:
import { BrowserRouter as Router } from 'react-router-dom';const App = () => (<Router>{/* 路由定义 */}</Router>
);
HashRouter
描述:使用 URL 的哈希部分(# 符号后面的部分)来管理路由。路由变化不会导致页面刷新,不会因为刷新页面而找不到对应路径;适用于不需要服务器配置的情况。适合静态页面或不支持 HTML5 History API 的环境(如一些旧版浏览器)。
使用:
import { HashRouter as Router } from 'react-router-dom';const App = () => (<Router>{/* 路由定义 */}</Router>
);
MemoryRouter
描述:不与浏览器的 URL 直接交互,而是将路由存储在内存中。适合测试和非浏览器环境(如 React Native)。用于需要控制路由状态但不需要与 URL 同步的情况。
使用:
import { MemoryRouter } from 'react-router-dom';const App = () => (<MemoryRouter>{/* 路由定义 */}</MemoryRouter>
);
StaticRouter
描述:用于服务器端渲染(SSR)的情况,不会改变浏览器的 URL。合在服务器上渲染 React 组件,通常与 react-router 的 match 函数一起使用。
使用:
import { StaticRouter } from 'react-router-dom';const App = () => (<StaticRouter location={req.url}>{/* 路由定义 */}</StaticRouter>
);
NativeRouter
描述:配合 React Native 使用,多用于移动端;
使用:
import { NativeRouter, Route } from 'react-router-native';import { Text, View } from 'react-native';const App = () => (<NativeRouter><Route path="/" exact><View><Text>Home</Text></View></Route><Route path="/about"><View><Text>About</Text></View></Route></NativeRouter>
);
Route
描述: 在所有路由模式中, 组件用于定义特定路径与组件之间的映射关系。
接受的props:
- path:页面 URL 应导航到的路径,类似于 NavLink 组件的 to;
- element:页面导航到该路由时加载的元素。
import { Route } from 'react-router-dom';const App = () => (<Router><Route path="/" element={<Home />} /></Router>
);
与Routes的区别
- Route 是定义单个路由的组件,表示特定路径和组件的映射。
- Routes 是一个容器组件,用于包裹多个 Route,并确保只渲染第一个匹配的路由。
路径跳转API
NavLink
使用:
1、先导入NavLink组件
import { NavLink } from "react-router-dom";
2、使用该组件,他是一个导航链接组件,类似于HTML中的标签,使用to来指定需要跳转的链接
<nav> <NavLink to="">首页</NavLink> <NavLink to="product">产品</NavLink> <NavLink to="about">关于</NavLink> </nav>
3、NavLink存在active状态,所以可以为active状态和非active状态的导航链接添加样式来进行区分,使其更加直观。
//为高亮的链接设置字体颜色为红色的样式
.nav-active {color: red;}
import { NavLink } from "react-router-dom";<nav> //来控制是否显示高亮<NavLinkto=""className={({ isActive }) => isActive ? "nav-active" : void 0}>
首页
</NavLink><NavLink to="product">产品</NavLink><NavLink to="about">关于</NavLink>
</nav>
Link
可以使用 Link 组件来创建常规链接。Link 组件与 NavLink 组件非常相似,唯一的区别就是 NavLink 存在 active 状态,而 Link 没有。
使用:
1、也使用to进行跳转路径
import { Link } from "react-router-dom";<Link to="/">返回首页</Link>
2、如果需要对 Link 进行更多控制,也可以传递给 to 一个对象,在这个对象中,可以通过 search 属性来添加查询字符串或通过 hash 属性来传递 hash值
import { Link } from "react-router-dom";<Link to={{pathname: "/settings",search: "?sort=date",hash: "#hash"}}>设置
</Link>
路由顺序
1. 匹配顺序
- 从上到下匹配: React Router 会根据定义的顺序从上到下匹配路由。也就是说,最上面的路由会首先被检查,如果它与当前的 URL 匹配,其他路由将不会被检查。
- 优先级: 更具体的路由应该放在更上面。例如,如果有一个路径 ‘/about’ 和一个更通用的路径 ‘/‘,则’ /about‘ 应该在上面定义,因为它是更具体的匹配。
示例:
import { Routes, Route } from 'react-router-dom';const App = () => (<Routes><Route path="/about" element={<About />} /> {/* 更具体的路由 */}<Route path="/" element={<Home />} /> {/* 更通用的路由 */}</Routes>
);
在这个例子中,如果路径是’ /about‘,则会渲染 About 组件。如果将 ’/ ‘路由放在 ’/about ‘之前,任何以 ‘/about ’开头的路径都将匹配到‘ / ’,导致 About 组件不会被渲染。
2. 嵌套路由
- 在使用嵌套路由时,外层路由的顺序同样重要,外层路由会优先匹配。
<Routes><Route path="/dashboard" element={<Dashboard />}><Route path="analytics" element={<Analytics />} /><Route path="reports" element={<Reports />} /></Route><Route path="/" element={<Home />} />
</Routes>
在这个示例中:
- 如果路径是 /dashboard/analytics,则会渲染 Dashboard 和 Analytics 组件。
- 如果路径是 /dashboard,则仅渲染 Dashboard 组件。
- 如果路径是 /,则渲染 Home 组件。
3.重定向和404处理
如果你使用了重定向或404处理,通常将它们放在最后,以确保所有其他路由都被尝试匹配后,再处理这些情况。
<Routes><Route path="/about" element={<About />} /><Route path="/" element={<Home />} /><Route path="*" element={<NotFound />} /> {/* 404 页面 */}
</Routes>
在这个例子中,NotFound 组件只会在没有其他匹配的情况下被渲染。
编程式导航
一. useNavigate
概述
useNavigate 是一个 Hook,允许你在函数组件中进行编程式导航。它可以用于在事件处理程序中、条件逻辑中或任何需要动态导航的地方。
使用方法
1、导入 useNavigate:
首先,确保从 react-router-dom 导入 useNavigate。
import { useNavigate } from 'react-router-dom';
2、调用 useNavigate:
在你的组件中调用 useNavigate,它会返回一个导航函数。
const navigate = useNavigate();
3、执行导航:
使用返回的函数进行导航,传入目标路径。
navigate('/about'); // 导航到 /about
二. Navigate
概述
Navigate 是一个组件,通常用于在渲染时进行导航。它可以在路由中声明性地使用,适合在需要条件导航的场景下,比如在某个条件满足时自动重定向。
使用方法
1、导入 Navigate:
确保从 react-router-dom 导入 Navigate。
import { Navigate } from 'react-router-dom';
2、使用 Navigate 组件:
在你的组件中使用 Navigate,传入 to 属性指定要导航到的路径。
return <Navigate to="/about" replace />;
传参并查询参数
第一种:SearchParams传参
navigate('/article?id=100&name=jack') //传参const [params]=useSearchParams(); //获取参数
let id=params.get('id')第二种:params传参,需要在路由文件中在路径中添加/:id
navigate('/article/1001')const params=useParams(); //获取参数
let id=params.id
通过路由传递状态
1、Link
使用 Link 组件通过 state props 来将数据传递
<Link to="/" state={"From Product"}>返回
</Link>
在接收信息的页面(首页)中使用一个名为 useLocation 的钩子来获取数据
import { useLocation } from "react-router-dom";...
let location = useLocation();
<p>{location.state}</p>
...
2、Navigate
Navigate 组件也可以在 react-router-dom 中传递状态,其使用方式和 Link 组件类似
<Route path="/about" element={<Navigate to="/" state={"From About"} />} />
接受方式同Link一致
3、useNavigate
用法:
import { useNavigate } from 'react-router-domfunction Register () {const navigate = useNavigate()return (<div><Form afterSubmit={() => navigate('/', { state: "From the About Page"})} /></div>)
}
接收方式同上面一致
总结
在构建 React 应用时,React Router 提供了灵活而强大的路由解决方案,使得管理导航和组件渲染变得简单高效,增强了用户体验和应用的可维护性。