一、React路由入门:从零开始理解路由

大家好,欢迎来到《React路由管理与权限控制实战》的第一章。

说实话,路由这个概念,刚接触前端的朋友可能会觉得有点抽象。我当年第一次听到「路由」这个词,还以为是网络设备里的那个路由器。后来才明白,前端路由说白了就是——根据不同的URL,展示不同的页面组件

这一章,我会带你从最基础的概念讲起。包括SPA和MPA的区别、路由的基本原理,以及如何安装配置React Router。嗯,咱们一步步来。

1.1 什么是SPA?什么是MPA?

先搞清楚这两个概念,因为React Router就是为SPA服务的。

对比项 SPA(单页应用) MPA(多页应用)
页面切换方式 前端JS控制,不刷新页面 每次跳转都请求新HTML
用户体验 流畅,无白屏闪烁 有页面刷新感
SEO 较差(需额外处理) 天然友好
首屏加载 较慢(需加载整个JS包) 较快(按需加载)
典型框架 React、Vue、Angular 传统jQuery、PHP、JSP

我个人习惯把SPA理解成「一个空壳子+一堆组件」。你访问网站时,服务器只给你一个空的HTML页面,剩下的所有内容,都由JavaScript动态渲染。而MPA呢,每次点击链接,浏览器都会向服务器要一个新的HTML文件。

核心区别一句话:SPA只加载一次页面,后续切换全靠JS;MPA每次切换都重新加载页面。

我在项目中遇到过不少刚转React的同事,他们总想把MPA那套思维带过来——每个页面单独写一个HTML。结果呢?路由跳转时页面闪一下,用户体验很差。其实在React里,我们只需要一个入口HTML就够了。

1.2 路由的基本原理

你可能会问:「不刷新页面,怎么改变URL?」

好问题。前端路由的核心就两个东西:

  • Hash模式:利用URL中的 # 部分。比如 http://example.com/#/home。改变 # 后面的内容,浏览器不会发起请求,但会触发 hashchange 事件。React Router监听这个事件,就能切换组件。
  • History模式:利用HTML5的 history.pushStatepopstate 事件。这种方式URL看起来更干净,比如 http://example.com/home。但需要后端配合,否则刷新页面会404。

避坑指南:我曾经在生产环境中只用History模式,结果部署到Nginx上,用户一刷新就白屏。后来才加上try_files配置。所以如果你用History模式,记得让后端把所有路由都指向你的index.html。

说白了,路由就是一套「URL ↔ 组件」的映射表。你访问 /home,我就渲染Home组件;你访问 /about,我就渲染About组件。React Router帮我们管理这张表。

1.3 React Router是什么?

React Router是React生态里最流行的路由库。目前最新稳定版是v6.x。我建议你直接学v6,因为v5和v4的API差异挺大,v6更简洁、更符合直觉。

它的核心功能就三个:

  • 声明式路由:用组件的方式定义路由,而不是写一堆if-else
  • 嵌套路由:一个路由里可以嵌套子路由,适合做布局
  • 导航与传参:支持编程式导航、URL参数、查询参数等

一句话总结:React Router让你在SPA里实现「看起来像多页面」的体验,但实际上是组件切换。

1.4 安装与配置React Router

好,理论讲完了,咱们动手。

第一步:安装

用npm或yarn安装:

# 使用npm
npm install react-router-dom

# 使用yarn
yarn add react-router-dom

注意,我们安装的是 react-router-dom,不是 react-routerreact-router-dom 包含了浏览器环境下的所有功能,比如 LinkBrowserRouter 等。如果你用React Native,才需要 react-router-native

第二步:包裹根组件

在项目的入口文件(通常是 index.jsmain.jsx)中,用 BrowserRouterHashRouter 包裹你的根组件:

import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

注意:BrowserRouter和HashRouter只能选一个,不能混用。我个人习惯开发时用HashRouter(省去后端配置),上线前改成BrowserRouter(URL更美观)。

第三步:定义路由

App.js 中,使用 RoutesRoute 组件定义路由映射:

import { Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';
import NotFound from './pages/NotFound';

function App() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
      <Route path="*" element={<NotFound />} />
    </Routes>
  );
}

export default App;

这里有几个要点:

  • Routes 是路由容器,它会匹配当前URL并渲染对应的 Route
  • Routepath 属性定义URL路径,element 属性定义要渲染的组件
  • path="*" 是通配符,匹配所有未定义的路由,通常用来做404页面

第四步:添加导航链接

Link 组件代替传统的 <a> 标签:

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

function Navbar() {
  return (
    <nav>
      <Link to="/">首页</Link>
      <Link to="/about">关于我们</Link>
    </nav>
  );
}

为什么不用 <a>?因为 <a> 会触发页面刷新,而 Link 只会改变URL并切换组件,没有页面刷新。

小技巧:如果你需要高亮当前激活的导航项,可以用 NavLink 代替 Link。它会自动添加一个 active 类名,方便你写样式。

1.5 一个完整的示例

把上面这些拼起来,就是一个最简单的React Router应用:

// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';

ReactDOM.createRoot(document.getElementById('root')).render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

// App.js
import { Routes, Route, Link } from 'react-router-dom';

function Home() {
  return <h2>首页</h2>;
}

function About() {
  return <h2>关于我们</h2>;
}

function App() {
  return (
    <div>
      <nav>
        <Link to="/">首页</Link> | <Link to="/about">关于</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </div>
  );
}

export default App;

运行起来,你会发现点击导航时,URL变了,但页面没有刷新。这就是SPA的魅力。

1.6 本章小结

这一章我们聊了:

  • SPA和MPA的区别——说白了就是一个页面切换不刷新,一个刷新
  • 路由的基本原理——Hash模式和History模式
  • React Router是什么——一套URL到组件的映射工具
  • 如何安装配置——三步走:安装、包裹、定义路由

嗯,基础打牢了,后面才能玩转嵌套路由、动态路由、权限控制这些高级功能。下一章,我会带你深入React Router v6的核心API,包括 useParamsuseNavigate 这些钩子函数。到时候咱们再聊。

如果你在配置过程中遇到任何问题,欢迎随时交流。我的经验是,路由配置出问题,90%都是因为忘记包裹 BrowserRouter,或者路径写错了。检查一下这两点,基本都能解决。