使用 React Router v6 在 React 中实现面包屑
面包屑在网页开发中非常重要,因为它们为用户提供了一种方法来跟踪他们在我们网页中的当前位置,并帮助我们的网页导航。
在本指南中,我们将使用 React-router v6 和 Bootstrap 在 React 中实现面包屑。
React-router v6 是 React 和 React Native 中使用的路由库,用于在网页或 Web 应用程序中导航。
我们的实现使用 Typescript,但它也可以轻松用于基于 Javascript 的项目。
设置
首先,如果尚未安装的话,让我们在我们的项目中安装react-router-dom:
npm 安装react-router-dom
或者替代方案,使用纱线:
纱线添加react-router-dom
让我们也安装 bootstrap 来设计我们的组件:
npm 安装引导
实现我们的组件
然后我们创建一个 Breadcrumbs.tsx 组件,它将包含面包屑的标记,还包括确定相对于根位置的当前位置的必要逻辑。
让我们首先为组件添加一个简单的标记:
<div className='text-primary'> <nav aria-label='breadcrumb'> <ol className='breadcrumb'> <li className='breadcrumb-item pointer'> <span className='bi bi-arrow-left-short me-1'></span> Back </li> </ol> </nav> </div>
该组件目前只有一个后退按钮。让我们为后退按钮添加一个简单的实现,这样当单击时,应该加载上一页:
const goBack = () => { window.history.back(); };
下一步将编写一个函数,该函数将使用 matchRoutes 函数来获取当前路由并应用转换来过滤出与当前路由相关的所有路由。
matchRoute 接受 AgnosticRouteObject 类型的对象数组并返回 AgnosticRouteMatch
另外需要注意的是,该对象必须包含名为 path 的属性。
让我们首先为我们的路线声明一个接口:
export interface IRoute { name: string; path: string; //Important }
然后让我们声明我们的路线:
const routes: IRoute[] = [ { path: '/home', name: 'Home' }, { path: '/home/about', name: 'About' }, { path: '/users', name: 'Users' }, { path: '/users/:id', name: 'User' }, { path: '/users/:id/settings/edit', name: 'Edit User Settings' } ];
我们还声明了一个变量来保存 useLocation 钩子,还声明了另一个变量来保存面包屑的状态:
const location = useLocation(); const [crumbs, setCrumbs] = useState<IRoute[]>([]);
接下来,让我们实现我们的功能:
const getPaths = () => { const allRoutes = matchRoutes(routes, location); const matchedRoute = allRoutes ? allRoutes[0] : null; let breadcrumbs: IRoute[] = []; if (matchedRoute) { breadcrumbs = routes .filter((x) => matchedRoute.route.path.includes(x.path)) .map(({ path, ...rest }) => ({ path: Object.keys(matchedRoute.params).length ? Object.keys(matchedRoute.params).reduce( (path, param) => path.replace(`:${param}`, matchedRoute.params[param] as string), path) : path, ...rest, })); } setCrumbs(breadcrumbs); };
在这里,我们首先获取与当前位置匹配的所有路线:
const allRoutes = matchRoutes(路线, 位置);
然后我们快速检查是否返回任何结果,并选择第一个:
常量匹配路由=所有路由? allRoutes[0] : null;
接下来,我们过滤掉所有与当前路由匹配的路由:
routes.filter((x) =>matchedRoute.route.path.includes(x.path))
然后让我们使用结果创建一个新数组,检查路径是否有参数,然后用参数值交换动态路由:
.map(({ path, ...rest }) => ({ path: Object.keys(matchedRoute.params).length ? Object.keys(matchedRoute.params).reduce( (path, param) => path.replace(`:${param}`, matchedRoute.params[param] as string), path ) : path, ...rest, }));
这确保了如果我们在路由中将路由声明为 /users/:id/edit 并将 id 传递为 1,那么我们将得到 /users/1/edit。
接下来,让我们在 useEffect 中调用我们的函数,以便它在每次我们的位置发生变化时运行:
useEffect(() => { getPaths(); }, [location]);
完成此操作后,我们就可以在标记中使用面包屑:
{crumbs.map((x: IRoute, key: number) => crumbs.length === key + 1 ? ( <li className='breadcrumb-item'>{x.name}</li> ) : ( <li className='breadcrumb-item'> <Link to={x.path} className=' text-decoration-none'> {x.name} </Link> </li> ) )}
在这里,显示所有的面包屑及其链接,除了最后一个仅显示名称的面包屑。
这样,我们现在就有了完整的 BreadCrumbs.tsx 组件:
import { useEffect, useState } from 'react'; import { Link, matchRoutes, useLocation } from 'react-router-dom'; export interface IRoute { name: string; path: string; } const routes: IRoute[] = [ { path: '/home', name: 'Home', }, { path: '/home/about', name: 'About', }, { path: '/users', name: 'Users', }, { path: '/users/:id/edit', name: 'Edit Users by Id', }, ]; const Breadcrumbs = () => { const location = useLocation(); const [crumbs, setCrumbs] = useState([]); // const routes = [{ path: '/members/:id' }]; const getPaths = () => { const allRoutes = matchRoutes(routes, location); const matchedRoute = allRoutes ? allRoutes[0] : null; let breadcrumbs: IRoute[] = []; if (matchedRoute) { breadcrumbs = routes .filter((x) => matchedRoute.route.path.includes(x.path)) .map(({ path, ...rest }) => ({ path: Object.keys(matchedRoute.params).length ? Object.keys(matchedRoute.params).reduce( (path, param) => path.replace(`:${param}`, matchedRoute.params[param] as string), path ) : path, ...rest, })); } setCrumbs(breadcrumbs); }; useEffect(() => { getPaths(); }, [location]); const goBack = () => { window.history.back(); }; return ( ); }; export default Breadcrumbs;
然后我们可以在应用程序的任何部分使用该组件,最好是在布局中。
结论
我们已经了解了如何实现一个简单的面包屑组件,我们可以将其添加到我们的应用程序中以改进导航和用户体验。
有用的链接
https://stackoverflow.com/questions/66265608/react-router-v6-get-path-pattern-for-current-route
https://medium.com/@mattywilliams/generating-an-automatic-breadcrumb-in-react-router-fed01af1fc3,这篇文章的灵感来自于此。
以上是使用 React Router v6 在 React 中实现面包屑的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

Python和JavaScript在开发环境上的选择都很重要。1)Python的开发环境包括PyCharm、JupyterNotebook和Anaconda,适合数据科学和快速原型开发。2)JavaScript的开发环境包括Node.js、VSCode和Webpack,适用于前端和后端开发。根据项目需求选择合适的工具可以提高开发效率和项目成功率。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。 1)C 用于解析JavaScript源码并生成抽象语法树。 2)C 负责生成和执行字节码。 3)C 实现JIT编译器,在运行时优化和编译热点代码,显着提高JavaScript的执行效率。
