前言
HashRouter
是 React Router
提供的一种路由实现方案,它使用 URL 的 hash 部分
(#
后面的内容)来实现客户端路由功能。
一、HashRouter 的核心用途
- 客户端路由:在不刷新页面的情况下管理应用导航
- 兼容性:支持不支持
HTML5 History API
的旧浏览器 - 静态服务器支持:不需要服务器配置,适合静态托管环境
- 路由隔离:hash 部分不会发送到服务器,完全由客户端处理
- 部署简单:无需服务器重定向配置
二、HashRouter
与 BrowserRouter 的主要区别
三、HashRouter
实现原理
HashRouter
利用 URL 的 hash 部分
(window.location.hash)来存储路由信息:
- 改变
hash
不会触发页面刷新 - 监听
hashchange
事件来响应路由变化 - 通过
window.location.hash
获取当前路由状态
四、HashRouter
完整代码示例
import React, { useState } from 'react';
import { HashRouter, Routes, Route, Link, NavLink, useNavigate, useParams, useLocation } from 'react-router-dom';
// 页面组件
const Home = () => (
<div className="page home">
<h2>🏠 欢迎来到首页</h2>
<p>这是一个使用 HashRouter 的 React 应用示例</p>
<div className="features">
<div className="feature-card">
<h3>兼容性强</h3>
<p>支持所有浏览器,包括旧版IE</p>
</div>
<div className="feature-card">
<h3>部署简单</h3>
<p>不需要服务器配置,适合静态托管</p>
</div>
<div className="feature-card">
<h3>路由隔离</h3>
<p>hash部分不会发送到服务器</p>
</div>
</div>
</div>
);
const About = () => (
<div className="page about">
<h2>📝 关于我们</h2>
<p>我们是一个专注于前端技术的团队,致力于提供最佳用户体验</p>
<div className="team">
<div className="member">
<div className="avatar">👨💻</div>
<h3>张三</h3>
<p>前端架构师</p>
</div>
<div className="member">
<div className="avatar">👩🎨</div>
<h3>李四</h3>
<p>UI设计师</p>
</div>
<div className="member">
<div className="avatar">👨🏫</div>
<h3>王五</h3>
<p>技术顾问</p>
</div>
</div>
</div>
);
// 产品列表页
const Products = () => {
const products = [
{ id: 1, name: 'React 教程', price: 99 },
{ id: 2, name: 'JavaScript 高级编程', price: 129 },
{ id: 3, name: 'CSS 大师课', price: 89 },
];
return (
<div className="page products">
<h2>🛒 产品列表</h2>
<div className="product-grid">
{products.map(product => (
<div key={product.id} className="product-card">
<div className="product-image">📚</div>
<h3>{product.name}</h3>
<p>¥{product.price}</p>
<Link to={`/products/${product.id}`} className="btn">
查看详情
</Link>
</div>
))}
</div>
</div>
);
};
// 产品详情页(动态路由)
const ProductDetail = () => {
const { id } = useParams();
const location = useLocation();
// 模拟产品数据
const products = {
1: { name: 'React 教程', description: '深入学习React框架的最佳指南', price: 99 },
2: { name: 'JavaScript 高级编程', description: '掌握JavaScript高级技巧', price: 129 },
3: { name: 'CSS 大师课', description: '成为CSS专家的必修课程', price: 89 },
};
const product = products[id] || {
name: '未知产品',
description: '该产品不存在',
price: 0
};
return (
<div className="page product-detail">
<h2>🔍 产品详情</h2>
<div className="product-info">
<div className="product-header">
<h3>{product.name}</h3>
<p className="price">¥{product.price}</p>
</div>
<p>{product.description}</p>
<p className="meta">产品ID: {id} | 当前路径: {location.pathname}</p>
<Link to="/products" className="btn">
← 返回产品列表
</Link>
</div>
</div>
);
};
// 登录页(演示编程式导航)
const Login = () => {
const navigate = useNavigate();
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleLogin = (e) => {
e.preventDefault();
// 模拟登录逻辑
if (username && password) {
// 登录成功后导航到仪表盘
navigate('/dashboard');
}
};
return (
<div className="page login">
<h2>🔑 用户登录</h2>
<form onSubmit={handleLogin}>
<div className="form-group">
<label>用户名</label>
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
placeholder="输入用户名"
/>
</div>
<div className="form-group">
<label>密码</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="输入密码"
/>
</div>
<button type="submit" className="btn">登录</button>
</form>
</div>
);
};
// 仪表盘页(受保护路由)
const Dashboard = () => {
return (
<div className="page dashboard">
<h2>📊 用户仪表盘</h2>
<p>欢迎访问您的个人仪表盘!</p>
<div className="stats">
<div className="stat-card">
<h3>28</h3>
<p>已完成课程</p>
</div>
<div className="stat-card">
<h3>12</h3>
<p>进行中课程</p>
</div>
<div className="stat-card">
<h3>5</h3>
<p>收藏课程</p>
</div>
</div>
</div>
);
};
// 404 页面
const NotFound = () => (
<div className="page not-found">
<h2>🔍 404 - 页面未找到</h2>
<p>抱歉,您访问的页面不存在</p>
<Link to="/" className="btn">
返回首页
</Link>
</div>
);
// 导航组件
const Navigation = () => {
const location = useLocation();
return (
<nav>
<div className="logo">
<Link to="/">HashRouter示例</Link>
</div>
<div className="nav-links">
<NavLink to="/" end className={({isActive}) => isActive ? 'active' : ''}>
首页
</NavLink>
<NavLink to="/about" className={({isActive}) => isActive ? 'active' : ''}>
关于
</NavLink>
<NavLink to="/products" className={({isActive}) => isActive ? 'active' : ''}>
产品
</NavLink>
<NavLink to="/login" className={({isActive}) => isActive ? 'active' : ''}>
登录
</NavLink>
</div>
<div className="location-info">
当前路径: <code>{location.pathname}</code>
</div>
</nav>
);
};
// 主应用组件
function App() {
return (
<HashRouter>
<div className="app">
<Navigation />
<main>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/products" element={<Products />} />
<Route path="/products/:id" element={<ProductDetail />} />
<Route path="/login" element={<Login />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="*" element={<NotFound />} />
</Routes>
</main>
<footer>
<p>使用 React Router HashRouter 实现 | 当前URL: {window.location.href}</p>
<div className="hash-info">
<strong>Hash部分:</strong> {window.location.hash}
</div>
</footer>
</div>
</HashRouter>
);
}
五、HashRouter
关键特性详解
5.1、 基本路由配置
<HashRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/products" element={<Products />} />
<Route path="*" element={<NotFound />} />
</Routes>
</HashRouter>
5.2、 动态路由参数
<Route path="/products/:id" element={<ProductDetail />} />
// 在组件中获取参数
const ProductDetail = () => {
const { id } = useParams();
// ...
}
5.3、 编程式导航
const Login = () => {
const navigate = useNavigate();
const handleLogin = () => {
// 登录逻辑...
navigate('/dashboard'); // 跳转到仪表盘
};
// ...
}
5.4、 导航链接
// 普通链接
<Link to="/about">关于我们</Link>
// 活动链接样式
<NavLink to="/products" className={({isActive}) =>
isActive ? 'active' : ''
}>
产品
</NavLink>
5.5、 获取位置信息
const location = useLocation();
console.log(location.pathname); // 当前路径
六、使用场景建议
- 静态网站托管:
GitHub Pages、Netlify、Vercel
等静态托管服务 - 旧版浏览器支持:需要兼容
IE9
等不支持History API
的浏览器 - 简单原型开发:快速搭建不需要复杂服务器配置的应用
- 混合应用:在传统多页应用中嵌入
SPA
模块
七、注意事项
- SEO 限制:搜索引擎对
hash
路由的索引支持有限 - URL 美观度:
URL 中的 #
符号可能影响美观 - 路由嵌套:与
BrowserRouter
的嵌套路由语法相同 - 锚点冲突:
hash
路由可能与传统页面锚点
功能冲突 - 服务器通信:
hash
部分不会发送到服务器
总结
HashRouter
是 React Router
提供的一种简单易用的路由解决方案,特别适合不需要服务器配置
或需要兼容旧浏览器
的场景。虽然它在 URL 美观度和 SEO 方面
不如 BrowserRouter
,但在特定环境下仍是不可或缺的工具。