- ReactJS 教程
- ReactJS - 首页
- ReactJS - 简介
- ReactJS - 路线图
- ReactJS - 安装
- ReactJS - 特性
- ReactJS - 优点与缺点
- ReactJS - 架构
- ReactJS - 创建 React 应用
- ReactJS - JSX
- ReactJS - 组件
- ReactJS - 嵌套组件
- ReactJS - 使用新创建的组件
- ReactJS - 组件集合
- ReactJS - 样式
- ReactJS - 属性 (props)
- ReactJS - 使用属性创建组件
- ReactJS - props 验证
- ReactJS - 构造函数
- ReactJS - 组件生命周期
- ReactJS - 事件管理
- ReactJS - 创建一个事件感知组件
- ReactJS - 在 Expense Manager APP 中引入事件
- ReactJS - 状态管理
- ReactJS - 状态管理 API
- ReactJS - 无状态组件
- ReactJS - 使用 React Hooks 进行状态管理
- ReactJS - 使用 React Hooks 的组件生命周期
- ReactJS - 布局组件
- ReactJS - 分页
- ReactJS - Material UI
- ReactJS - Http 客户端编程
- ReactJS - 表单编程
- ReactJS - 受控组件
- ReactJS - 非受控组件
- ReactJS - Formik
- ReactJS - 条件渲染
- ReactJS - 列表
- ReactJS - Keys
- ReactJS - 路由
- ReactJS - Redux
- ReactJS - 动画
- ReactJS - Bootstrap
- ReactJS - Map
- ReactJS - 表格
- ReactJS - 使用 Flux 管理状态
- ReactJS - 测试
- ReactJS - CLI 命令
- ReactJS - 构建和部署
- ReactJS - 示例
- Hooks
- ReactJS - Hooks 简介
- ReactJS - 使用 useState
- ReactJS - 使用 useEffect
- ReactJS - 使用 useContext
- ReactJS - 使用 useRef
- ReactJS - 使用 useReducer
- ReactJS - 使用 useCallback
- ReactJS - 使用 useMemo
- ReactJS - 自定义 Hooks
- ReactJS 高级
- ReactJS - 可访问性
- ReactJS - 代码分割
- ReactJS - Context
- ReactJS - 错误边界
- ReactJS - 转发 Refs
- ReactJS - Fragments
- ReactJS - 高阶组件
- ReactJS - 与其他库集成
- ReactJS - 性能优化
- ReactJS - Profiler API
- ReactJS - Portals
- ReactJS - 无 ES6 ECMAScript 的 React
- ReactJS - 无 JSX 的 React
- ReactJS - Reconciliation (协调)
- ReactJS - Refs 和 DOM
- ReactJS - Render Props
- ReactJS - 静态类型检查
- ReactJS - Strict Mode (严格模式)
- ReactJS - Web Components
- 其他概念
- ReactJS - 日期选择器
- ReactJS - Helmet
- ReactJS - 内联样式
- ReactJS - PropTypes
- ReactJS - BrowserRouter
- ReactJS - DOM
- ReactJS - 走马灯
- ReactJS - 图标
- ReactJS - 表单组件
- ReactJS - 参考 API
- ReactJS 有用资源
- ReactJS - 快速指南
- ReactJS - 有用资源
- ReactJS - 讨论
ReactJS - BrowserRouter
路由是前端应用中的一个重要概念。React 社区提供了一个优秀的路由库,称为 React Router。本章我们将学习 React 路由的概念以及如何在 React 应用中使用它。
路由概念
路由的主要目的是将给定的 URL 匹配到一个 React 组件并渲染匹配的组件。除了匹配和渲染之外,路由还应该管理浏览器的历史记录,以便在浏览器中实现高效的前进和后退导航。
在了解路由的工作原理之前,让我们了解一些 React Router 库的有用组件。
BrowserRouter − BrowserRouter 是顶级组件。它创建一个历史记录(导航历史记录),将初始位置(表示“用户当前位置”的路由对象)放入 React 状态中,最后订阅位置 URL。
<BrowserRouter> <!-- children --> </BrowserRouter>
Routes − Routes 将递归其子节点并构建路由配置。它将配置的路由与位置匹配,并渲染第一个匹配的路由元素。
<BrowserRouter> <Routes> <Route path="/" element={<App />}> <Route index element={<Home />} /> <Route path="admin" element={<Admin />}> <Route path="product" element={<ProductListing />} /> <Route path="category" element={<CategoryListing />} /> <Route index element={<Dashboard />} /> </Route> </Route> <Route path="/login" element={<Login />}> <!-- more nested routes --> </Route> <!-- more routes --> </Routes> </BrowserRouter>
这里:
/ 路径映射到 App 组件。
/ 路径的索引组件映射到 Home 组件。
/admin 路径映射到 Admin 组件。
/admin 路径的索引组件映射到 Dashboard 组件。
/admin/product 路径匹配到 ProductListing 组件。
/admin/category 路径匹配到 CategoryListing 组件。
/admin/dashboard 路径匹配到 Dashboard 组件。
Route − Route 是实际的路由配置。它可以像文件夹一样嵌套到任何级别。
Outlet − Outlet 组件渲染一组匹配中的下一个匹配项。
function Hello() { return ( <div>Hello</div> <Outlet /> ) }
这里:
将 Outlet 组件放置在 hello 组件的底部。
路由器将在 Outlet 组件内渲染下一个匹配项。
Link − Link 组件类似于锚点标签,用于导航目的。一旦用户点击它,它就会根据其 to 属性更改位置。
<Link to="/admin" />
navigate() − navigate() 是一个用于导航目的的 API,类似于 Link 组件。
navigate("/admin")
路由工作流程
让我们考虑一个 React 应用程序具有如下所示的五个页面/组件:
首页 (/)
联系 (/contact)
注册 (/register)
管理员 (/admin)
管理员仪表盘 (/admin/dashboard)
一个示例路由配置如下:
<BrowserRouter> <Routes> <Route path="/" element={<App />}> <Route index element={<Home />} /> <Route path="contact" element={<Contact />} /> <Route path="register" element={<Register />} /> <Route path="admin" element={<Admin />}> <Route path="dashboard" element={<AdminDashboard />} /> <Route path="category" element={<CategoryListing />} /> <Route index element={<AdminDashboard />} /> </Route> </Routes> </BrowserRouter>
让我们看看管理员仪表盘 URL (/admin/dashboard) 如何被 React 路由匹配和渲染。
首先,React 库将渲染我们的应用程序。由于我们的应用程序在渲染树的顶部具有 BrowserRouter,因此它会被调用和渲染。
BrowserRouter 组件创建一个历史记录,将初始位置放入状态中,并订阅 URL。
Routes 组件将检查其所有子节点,构建路由配置,最后渲染第一个匹配项 (/admin => )
Admin 组件将被渲染。它将有一个 Outlet 组件,如下所示:
function Admin() { return ( <div> <!-- Admin content --> </div> <Outlet /> ) }
Outlet 组件在其内部渲染下一个匹配项 (/admin/dashboard => )
用户可能会点击仪表盘中的一个链接(Link 组件),例如“/admin/category”
Link 组件调用 navigate("/admin/category") 方法
历史记录 (对象) 更改 URL 并通知 BrowserRouter
由于 BrowserRouter 组件已订阅 URL,因此 BrowserRouter 组件将重新渲染,整个过程将重复(从 2 开始)。
如何应用路由
首先,创建一个新的 React 应用程序,并使用以下命令启动它。
create-react-app myapp cd myapp npm start
接下来,使用以下命令安装 React Router 库:
npm install --save react-router-dom
接下来,打开 App.css (src/App.css) 并删除所有 CSS 类。
// remove all css classes
接下来,在 src 下创建一个文件夹 Pages,并创建一个新的主页组件 Home (src/Pages/Home.js),并渲染简单的主页内容,如下所示:
function Home() { return <h3>Home</h3> } export default Home
接下来,创建一个新的问候页面组件 Greeting (src/Pages/Greeting.js),并渲染简单的问候消息,如下所示:
function Greeting() { return <h3>Hello World!</h3> } export default Greeting;
接下来,打开 App.js 文件并渲染一个 BrowserRoutes 组件,如下所示:
import './App.css' import React from 'react'; import { BrowserRouter, Route, Routes } from 'react-router-dom'; import Layout from './Pages/Layout'; import Home from './Pages/Home'; import Greeting from './Pages/Greeting'; function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Layout />}> <Route index element={<Home />} /> <Route path="greet" element={<Greeting />} /> </Route> </Routes> </BrowserRouter> ); } export default App;
这里:
BrowserRouter 是主要组件。它将拥有路由设置作为其子组件,并根据路由设置渲染整个应用程序。
Routes 是主要的路由组件。它保存单个路由设置的列表。
Route 是实际的路由组件,它具有 web 路径 (/home) 和组件 (Home) 之间的映射。
Route 可以嵌套以支持嵌套路径。
路由中定义的映射如下:
/ 映射到 Layout 组件。Layout 组件将在下一步创建。
/home 映射到 Home 组件,它嵌套在 / 路径下。
/greet 映射到 Greet 组件,它嵌套在 / 路径下。
接下来,创建一个布局组件 Layout (src/Pages/Layout.js)。布局组件的目的是显示带有导航链接的整个应用程序。它是应用程序的主要组件,指向 / 路由。Layout 组件的源代码如下:
import { Outlet, Link } from "react-router-dom"; function Layout() { return ( <> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/greet">Greeting</Link> </li> </ul> </nav> <Outlet /> </> ) } export default Layout;
这里:
导入了 Link 和 Outlet 组件。
Link 组件用于创建 web 导航链接。
Link 组件的 to 属性设置为父 BrowserRouter 组件中定义的路由之一。
使用了 / 和 /greet 路由,它们在路由设置中可用。
Outlet 组件用于底部加载选定的组件。在初始渲染期间,它将加载默认组件 (home)。
一旦用户点击 web 链接,它将从 to 属性获取路由路径,并通过路由设置获取映射的组件。最后,它将在 Outlet 组件内渲染组件。
接下来,创建一个新组件 PageNotAvailable (src/Pages/PageNotAvailable.js),用于显示链接与任何路由设置都不匹配的情况。
import { Link } from "react-router-dom" function PageNotAvailable() { return ( <p>The page is not available. Please <Link to= "/">click here</Link> to go to home page.</p> ) } export default PageNotAvailable
这里,Link 组件用于导航回主页。
接下来,更新 App 组件并在路由设置中包含 PageNotAvailable 组件。
import './App.css' import React from 'react'; import { BrowserRouter, Route, Routes } from 'react-router-dom'; import Layout from './Pages/Layout'; import Home from './Pages/Home'; import Greeting from './Pages/Greeting'; import PageNotAvailable from './Pages/PageNotAvailable' function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Layout />}> <Route index element={<Home />} /> <Route path="greet" element={<Greeting />} /> <Route path="*" element={<PageNotAvailable />} /> </Route> </Routes> </BrowserRouter> ); } export default App;
这里:
当用户点击链接时,React 路由器将尝试按照给定的顺序一一匹配点击的链接和路由设置。如果匹配到链接,则 React 路由器将停止并渲染匹配的组件。
* 模式将匹配所有链接。由于它作为最后一个条目放置,因此它将匹配所有未定义/未知链接。
接下来,更新 Layout 组件并添加一个不可用的链接来检查 PageNotAvailable 组件是否已正确配置。
import { Outlet, Link } from "react-router-dom"; function Layout() { return ( <> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/greet">Greeting</Link> </li> <li> <Link to="/unknown">Unavailable page</Link> </li> </ul> </nav> <Outlet /> </> ) } export default Layout;
最后,在浏览器中打开应用程序并检查最终结果。应用程序将按如下所示进行渲染:
用户可以使用上面输出中显示的导航链接导航到任何页面。
总结
React Router 易于配置和使用。它没有太多花哨的功能,但具有必要的特性,例如链接、出口、路由和路由,可以创建一个具有导航链接的完整 web 应用程序。