React-Router 的工作原理
React-Router 是 React 官方提供的前端路由解决方案,它的核心原理是:
通过监听 URL 地址变化,动态渲染对应的组件,从而实现页面的跳转和切换。
React-Router 的核心原理
React-Router 通过以下核心机制实现路由跳转:
✅ 1. 基于 History API 或 Hash 实现 URL 变化
React-Router 支持两种路由模式:
模式 | 实现原理 |
---|---|
Hash 模式 | 使用 window.location.hash 监听 URL 变化实现页面跳转。地址带 # ,如:http://localhost:3000/#/home |
History 模式 | 使用 window.history.pushState / window.history.replaceState 修改 URL,实现无刷新跳转。地址无 # ,如:http://localhost:3000/home |
2. 监听 URL 地址变化
React-Router 内部通过事件监听 来感知 URL 变化:#### Hash 模式
- 监听
window.onhashchange
事件,当location.hash
变化时,重新渲染对应的页面组件。
javascript
window.onhashchange = () => {
console.log('地址变化了', window.location.hash);
}
History 模式
- 通过
popstate
事件监听 URL 变化:
javascript
window.onpopstate = (event) => {
console.log('地址变化了', window.location.pathname);
}
- 通过
pushState
/replaceState
修改 URL:
javascript
window.history.pushState({}, '', '/about');
History 模式更优雅 ,但需要后端配合配置 404 重定向
。
3. Route 通过 URL 匹配组件
React-Router 内部通过 路径匹配找到对应的组件:
ini
<Route path="/home" element={<Home />} />
<Route path="/about" element={<About />} />
匹配原理:
ini
const path = window.location.pathname;
if (path === '/home') render(<Home />);
if (path === '/about') render(<About />);
4. 页面跳转的核心:Link / navigate
React-Router 提供了 <Link />
或 useNavigate()
进行跳转:
- 通过
window.history.pushState()
修改 URL:
ini
<Link to="/about">跳转关于页面</Link>
- useNavigate() 通过
pushState
实现跳转:
ini
import { useNavigate } from 'react-router-dom';
const Home = () => {
const navigate = useNavigate();
return <button onClick={() => navigate('/about')}>跳转</button>;
}
原理 :跳转页面时不刷新页面,只修改 URL,React-Router 自动渲染对应的组件。
5. 动态路由匹配
React-Router 支持动态路由匹配: <Route path="/user/:id" element={} /> 访问 /user/123 会匹配:
javascript
import { useParams } from 'react-router-dom';
const User = () => {
const { id } = useParams();
return <h1>用户ID: {id}</h1>;
}
匹配原理:
ini
const path = window.location.pathname; // /user/123
const match = /^\/user\/(\d+)$/.exec(path);
if (match) render(<User id={match[1]} />);
6. 路由守卫 (Navigation Guard)
React-Router 通过 useEffect
或 Navigate
实现路由守卫:
- 未登录跳转登录页:
javascript
import { useNavigate } from 'react-router-dom';
const Dashboard = () => {
const navigate = useNavigate();
useEffect(() => {
if (!localStorage.getItem('token')) {
navigate('/login');
}
}, []);
return <h1>欢迎进入系统</h1>;
}
原理:
- 页面加载时检查
localStorage
是否存在token
。 - 如果不存在,调用
navigate()
重定向至登录页。
✅ React-Router-Dom 组件介绍
以下是 React-Router-Dom 常用的核心组件:
1. BrowserRouter (必须包裹根组件)
✅ BrowserRouter 提供基于 History 模式的路由功能:
javascript
import { BrowserRouter } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
📌 2. HashRouter (基于 Hash 模式)
✅ HashRouter 使用 #
实现路由跳转:
javascript
jsx
复制编辑
import { HashRouter } from 'react-router-dom';
function App() {
return (
<HashRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</HashRouter>
);
}
特点:
- URL 带
#
:http://localhost:3000/#/home
- 优点:无后端配置,前端直接可用。
- 缺点:URL 不优雅,SEO 差。
📌 3. Route (定义路由)
✅ Route 负责匹配 URL并渲染对应组件:
ini
jsx
<Route path="/home" element={<Home />} />
<Route path="/about" element={<About />} />
path
:路径element
:渲染组件
📌 4. Routes (包裹所有路由)
✅ React 18+ 必须使用 Routes
包裹 Route
:
xml
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
特点:
- React 18 强制要求 Route 必须包裹在 Routes 内部。
📌 5. Link (跳转页面)
✅ Link 用于代替 <a>
标签:
ini
jsx
<Link to="/about">关于</Link>
- 不刷新页面
- 修改 URL 地址
底层原理:
javascript
window.history.pushState({}, '', '/about');
📌 6. useNavigate (编程式跳转)
✅ useNavigate() 替代 useHistory()
:
ini
import { useNavigate } from 'react-router-dom';
const Home = () => {
const navigate = useNavigate();
return (
<button onClick={() => navigate('/about')}>
跳转关于页面
</button>
);
}
- 内部调用:
javascript
window.history.pushState({}, '', '/about');
📌 7. useParams (获取动态参数)
✅ 获取 URL 参数:
ini
jsx
复制编辑
<Route path="/user/:id" element={<User />} />
javascript
jsx
复制编辑
import { useParams } from 'react-router-dom';
const User = () => {
const { id } = useParams();
return <h1>ID: {id}</h1>;
}
- 访问
/user/123
,id
就是123
。
📌 8. Navigate (路由重定向)
✅ 类似 window.location.replace
:
javascript
import { Navigate } from 'react-router-dom';
if (!localStorage.getItem('token')) {
return <Navigate to="/login" />;
}
- 内部调用:
javascript
window.location.replace('/login');
✅ 总结
组件 | 作用 |
---|---|
BrowserRouter | History 模式 |
HashRouter | Hash 模式 |
Route | 定义路由 |
Routes | 包裹所有路由 |
Link | 跳转页面 |
useNavigate | 编程式跳转 |