学习记录-react-router&基础篇

672 阅读3分钟

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 变化时,重新渲染对应的页面组件。
window.onhashchange = () => {
  console.log('地址变化了', window.location.hash);
}

History 模式

  • 通过 popstate 事件监听 URL 变化:
window.onpopstate = (event) => {
  console.log('地址变化了', window.location.pathname);
}
  • 通过 pushState / replaceState 修改 URL:
window.history.pushState({}, '', '/about');

History 模式更优雅,但需要后端配合配置 404 重定向

3. Route 通过 URL 匹配组件

React-Router 内部通过 路径匹配找到对应的组件:

<Route path="/home" element={<Home />} />
<Route path="/about" element={<About />} />

匹配原理:

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:
<Link to="/about">跳转关于页面</Link>
  • useNavigate() 通过 pushState 实现跳转:
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 会匹配:

import { useParams } from 'react-router-dom';

const User = () => {
  const { id } = useParams();
  return <h1>用户ID: {id}</h1>;
}

匹配原理:

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 通过 useEffectNavigate 实现路由守卫:

  • 未登录跳转登录页
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 模式的路由功能:

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 使用 # 实现路由跳转:

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并渲染对应组件:

jsx
<Route path="/home" element={<Home />} />
<Route path="/about" element={<About />} />
  • path:路径
  • element:渲染组件

📌 4. Routes (包裹所有路由)

✅ React 18+ 必须使用 Routes 包裹 Route

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />} />
</Routes>

特点:

  • React 18 强制要求 Route 必须包裹在 Routes 内部。

📌 5. Link (跳转页面)

Link 用于代替 <a> 标签:

jsx
<Link to="/about">关于</Link>
  • 不刷新页面
  • 修改 URL 地址

底层原理:

window.history.pushState({}, '', '/about');

📌 6. useNavigate (编程式跳转)

useNavigate() 替代 useHistory()

import { useNavigate } from 'react-router-dom';

const Home = () => {
  const navigate = useNavigate();
  return (
    <button onClick={() => navigate('/about')}>
      跳转关于页面
    </button>
  );
}
  • 内部调用:
window.history.pushState({}, '', '/about');

📌 7. useParams (获取动态参数)

✅ 获取 URL 参数:

jsx
复制编辑
<Route path="/user/:id" element={<User />} />
jsx
复制编辑
import { useParams } from 'react-router-dom';

const User = () => {
  const { id } = useParams();
  return <h1>ID: {id}</h1>;
}
  • 访问 /user/123id 就是 123

📌 8. Navigate (路由重定向)

✅ 类似 window.location.replace

import { Navigate } from 'react-router-dom';

if (!localStorage.getItem('token')) {
  return <Navigate to="/login" />;
}
  • 内部调用:
window.location.replace('/login');

✅ 总结

组件作用
BrowserRouterHistory 模式
HashRouterHash 模式
Route定义路由
Routes包裹所有路由
Link跳转页面
useNavigate编程式跳转