当前位置: 首页 > news >正文

React第六十节 Router中createHashRouter的具体使用详解及案例分析

前言

createHashRouterReact Router 提供的一种特殊路由器,它使用 URL 的哈希部分(#)来处理客户端路由。
这种路由方式特别适用于静态网站托管服务(如 GitHub Pages)或无法配置服务器以支持 HTML5 History API 的场景。

一、createHashRouter 的主要用途

  1. 无服务器配置要求:不需要服务器端重写规则
  2. 静态网站兼容:完美适配 GitHub Pages 等静态托管服务
  3. 旧浏览器支持:兼容不支持 HTML5 History API 的浏览器
  4. 简单部署:避免处理服务器配置问题
  5. 本地开发便利:在本地文件系统上也能正常工作

二、createHashRouter 与 createBrowserRouter 的关键区别

在这里插入图片描述

三、createHashRouter 完整代码示例

3.1、 基础路由配置

// src/main.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import {createHashRouter,RouterProvider,Link,Outlet,useLocation
} from 'react-router-dom';// 页面组件
function Home() {return (<div className="page home"><h1>首页</h1><p>欢迎使用哈希路由示例应用</p><div className="page-nav"><Link to="/about" className="nav-link">关于我们</Link><Link to="/products" className="nav-link">产品列表</Link></div></div>);
}function About() {return (<div className="page about"><h1>关于我们</h1><p>我们是一家专注于前端技术的公司</p><Link to="/" className="back-link">返回首页</Link></div>);
}// 布局组件
function RootLayout() {const location = useLocation();return (<div className="app"><header className="app-header"><h1 className="logo">哈希路由示例</h1><div className="url-display">当前路由: <code>{location.pathname || '/'}</code></div><nav className="main-nav"><Link to="/" className="nav-item">首页</Link><Link to="/about" className="nav-item">关于</Link><Link to="/products" className="nav-item">产品</Link></nav></header><main className="app-content"><Outlet /> {/* 子路由渲染位置 */}</main><footer className="app-footer"><p>当前使用: <code>createHashRouter</code> | © 2023 React Router 示例</p></footer></div>);
}// 创建哈希路由配置
const router = createHashRouter([{path: "/",element: <RootLayout />,children: [{index: true,element: <Home />},{path: "about",element: <About />},{path: "products",element: <ProductsList />,children: [{path: ":productId",element: <ProductDetail />}]}]}
]);// 产品列表组件
function ProductsList() {const products = [{ id: 1, name: 'React 教程', price: 99 },{ id: 2, name: 'Node.js 实战', price: 129 },{ id: 3, name: 'TypeScript 指南', price: 89 }];return (<div className="page products"><h1>产品列表</h1><div className="products-grid">{products.map(product => (<div key={product.id} className="product-card"><h3><Link to={`/products/${product.id}`}>{product.name}</Link></h3><p>价格: ¥{product.price}</p></div>))}</div><Link to="/" className="back-link">返回首页</Link></div>);
}// 产品详情组件
function ProductDetail() {const { productId } = useParams();const products = {1: { id: 1, name: 'React 教程', description: '深入学习 React 框架', price: 99 },2: { id: 2, name: 'Node.js 实战', description: '构建高性能后端应用', price: 129 },3: { id: 3, name: 'TypeScript 指南', description: '掌握类型安全的JavaScript', price: 89 }};const product = products[productId];if (!product) {return (<div className="error"><h2>产品未找到</h2><p>没有找到ID{productId} 的产品</p><Link to="/products" className="back-link">返回产品列表</Link></div>);}return (<div className="page product-detail"><h1>{product.name}</h1><p className="description">{product.description}</p><p className="price">价格: ¥{product.price}</p><Link to="/products" className="back-link">返回产品列表</Link></div>);
}// 渲染应用
ReactDOM.createRoot(document.getElementById('root')).render(<React.StrictMode><RouterProvider router={router} /></React.StrictMode>
);

3.2、 带数据加载的高级示例

// 在 main.jsx 中添加以下内容
import { useLoaderData } from 'react-router-dom';// 创建模拟API函数
async function fetchProduct(productId) {// 模拟API延迟await new Promise(resolve => setTimeout(resolve, 500));const products = {1: { id: 1, name: 'React 教程', description: '深入学习 React 框架', price: 99, reviews: 24 },2: { id: 2, name: 'Node.js 实战', description: '构建高性能后端应用', price: 129, reviews: 18 },3: { id: 3, name: 'TypeScript 指南', description: '掌握类型安全的JavaScript', price: 89, reviews: 32 }};return products[productId] || null;
}// 更新产品详情组件使用加载器
function ProductDetail() {const product = useLoaderData();if (!product) {return (<div className="error"><h2>产品未找到</h2><p>请求的产品不存在</p><Link to="/products" className="back-link">返回产品列表</Link></div>);}return (<div className="page product-detail"><h1>{product.name}</h1><p className="description">{product.description}</p><div className="product-meta"><span className="price">价格: ¥{product.price}</span><span className="reviews">评价: {product.reviews}</span></div><Link to="/products" className="back-link">返回产品列表</Link></div>);
}// 添加产品加载器
async function productLoader({ params }) {const product = await fetchProduct(params.productId);if (!product) {throw new Response('Product Not Found', { status: 404 });}return product;
}// 更新路由配置
const router = createHashRouter([{path: "/",element: <RootLayout />,children: [// ...其他路由{path: "products",element: <ProductsList />,children: [{path: ":productId",element: <ProductDetail />,loader: productLoader,errorElement: <div className="error">产品加载失败</div>}]}]}
]);

3.3、 表单处理示例

// 添加联系表单页面
function Contact() {return (<div className="page contact"><h1>联系我们</h1><ContactForm /><Link to="/" className="back-link">返回首页</Link></div>);
}// 联系表单组件
function ContactForm() {return (<form className="contact-form" method="post" action="/contact"><div className="form-group"><label htmlFor="name">姓名</label><input type="text" id="name" name="name" required placeholder="请输入您的姓名"/></div><div className="form-group"><label htmlFor="email">邮箱</label><input type="email" id="email" name="email" required placeholder="请输入您的邮箱"/></div><div className="form-group"><label htmlFor="message">留言</label><textarea id="message" name="message" required rows="5"placeholder="请输入您的留言内容"></textarea></div><button type="submit" className="submit-btn">提交</button></form>);
}// 联系表单处理器
async function contactAction({ request }) {const formData = await request.formData();const data = Object.fromEntries(formData);// 在实际应用中,这里会发送数据到服务器console.log('收到联系表单:', data);// 显示成功消息return { success: true, message: '感谢您的留言,我们会尽快回复!' };
}// 更新路由配置
const router = createHashRouter([{path: "/",element: <RootLayout />,children: [// ...其他路由{path: "contact",element: <Contact />,action: contactAction}]}
]);

四、createHashRouter 核心特性详解

4.1、哈希路由工作原理

哈希路由使用 URL 的哈希部分(# 之后的内容)来管理应用状态:

text
http://example.com/#/about
http://example.com/#/products/123
  1. 哈希部分的变化不会触发页面刷新
  2. 服务器只接收 http://example.com/ 请求
  3. 路由完全在客户端处理

4.2、 路由配置

配置方式与 createBrowserRouter 相同:

const router = createHashRouter([{path: "/",element: <Layout />,children: [{ index: true, element: <Home /> },{ path: "about", element: <About /> },{ path: "contact", element: <Contact /> }]}
]);

4.3、 数据加载(loader

{path: "products/:id",element: <ProductDetail />,loader: async ({ params }) => {const response = await fetch(`/api/products/${params.id}`);return response.json();}
}

4.4、 表单处理(action

{path: "contact",element: <Contact />,action: async ({ request }) => {const formData = await request.formData();// 处理表单数据return redirect('/thank-you');}
}

4.5、 错误处理

{path: "/",element: <Layout />,errorElement: <GlobalError />,children: [{path: "products/:id",element: <ProductDetail />,errorElement: <ProductError />,loader: productLoader}]
}

4.6、 编程式导航

import { useNavigate } from 'react-router-dom';function LoginButton() {const navigate = useNavigate();const handleLogin = () => {// 执行登录逻辑...navigate('/dashboard');};return <button onClick={handleLogin}>登录</button>;
}

五、最佳实践

5.1、 部署到 GitHub Pages

  1. 创建 React 应用:npx create-react-app my-app
  2. 安装 React Router:npm install react-router-dom
  3. 配置哈希路由
  4. 在 package.json 中添加:
json
"homepage": "https://<username>.github.io/<repo-name>",
"scripts": {"predeploy": "npm run build","deploy": "gh-pages -d build"
}
  1. 安装 gh-pages:npm install gh-pages --save-dev
  2. 部署:npm run deploy

5.2、 处理深链接

由于哈希路由不需要服务器配置,深链接可以直接工作:

text
https://username.github.io/repo/#/products/123

5.3、 SEO 优化策略

虽然哈希路由对 SEO 不友好,但可以采取以下策略:

  1. 使用服务端渲染(SSR)替代
  2. 添加预渲染(如使用 react-snap)
  3. 提供静态元数据:
html
<meta name="description" content="产品详情页">

5.4、 性能优化

代码分割:

const ProductDetail = React.lazy(() => import('./ProductDetail'));{path: "products/:id",element: (<React.Suspense fallback={<div>加载中...</div>}><ProductDetail /></React.Suspense>)
}

数据预加载:

<Link to="/products/123" onMouseEnter={() => preloadProductData(123)}
>产品详情
</Link>

六、createHashRouter使用场景推荐

  1. GitHub Pages 项目:个人作品集、项目文档
  2. 静态网站:营销页面、活动页面
  3. 本地文件协议:file:// 协议下的应用
  4. 浏览器扩展:Chrome/Firefox 扩展的弹出页面
  5. 临时演示:快速分享原型演示
  6. 旧浏览器支持:需要兼容 IE9 等旧浏览器

总结

createHashRouterReact Router 提供的一种特殊路由解决方案,它通过 URL 的哈希部分实现客户端路由

主要特点包括:

  1. 无需服务器配置:适用于静态托管环境
  2. 广泛兼容性:支持所有现代和旧版浏览器
  3. 简单易用:与标准路由 API 完全兼容
  4. 快速部署:特别适合 GitHub Pages 等平台

虽然哈希路由在 URL 美观性和 SEO 方面存在不足,但在以下场景中它是理想选择:

  1. 静态网站托管(GitHub Pages、Netlify、Vercel 等)

  2. 无法配置服务器重定向规则的环境

  3. 需要支持旧版浏览器的应用

  4. 本地文件系统运行的应用程序

通过结合 React Router 的数据加载、表单处理和错误边界功能,createHashRouter 可以构建功能完善的单页应用,同时享受简单部署的便利性。

相关文章:

  • 安信可(云知声蜂鸟US516P6)SDK开发学习---log日志打印子系统模块
  • 蓝桥杯等竞赛场景下 C++ 的时间与空间复杂度深度解析​
  • Python打卡第51天
  • 文献管理软件EndNote下载与安装教程(详细教程)2025最新版详细图文安装教程
  • MySQL查看连接情况
  • 力扣-347.前K个高频元素
  • (ML-Agents) 是一个开源项目,它使游戏和模拟能够作为使用深度强化学习和模仿学习训练智能代理的环境
  • 建造者模式(Builder Pattern)
  • Go 通道(Channel)入门与基础使用
  • ZZU-ARM汇编语言实验2
  • 41页PPT | 基于AI制造企业解决方案架构设计智能制造AI人工智能应用智能质检人工智能质检建设
  • 在C# 中使用建造者模式
  • Spring cloud-k8s容器化部署
  • 同步与异步:软件工程中的时空艺术与实践智慧-以蜻蜓hr人才系统举例-优雅草卓伊凡
  • 记录rust滥用lazy_static导致的一个bug
  • 论文笔记 - 《Implementing block-sparse matrix multiplication kernels using Triton》
  • Linux【7】------Linux系统编程(进程间通信IPC)
  • docker-compose和docker下载
  • mysql DQL(javaweb第七天)
  • 博客:基本框架设计(下)
  • 网站效果图确认表/seo诊断
  • 房地产微网站建设栏目设计/市场营销课程
  • 东莞营销型网站建设费用/营销方法有哪些方式
  • 盐山做网站/互联网销售平台
  • 创意网站 案例 下载/搜索引擎优化指南
  • 郴州市第四人民医院/网站seo优化方案策划书