零基础全栈 React 入门(四):React Router 路由配置

🚀 零基础全栈 React 入门(四):React Router 路由配置

一、什么是 React Router?

1.1 路由的作用

React Router 是 React 应用中实现单页应用(SPA)路由的标准库。

路由的作用:

  • 根据 URL 路径显示不同的页面组件
  • 实现页面间的导航
  • 支持动态路由参数
  • 管理浏览器历史记录

1.2 安装 React Router

bash 复制代码
# 安装 React Router DOM(适用于 Web 应用)
npm install react-router-dom

二、基础路由配置

2.1 创建路由组件

jsx 复制代码
// src/App.js
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './Home';
import About from './About';
import Contact from './Contact';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        {/* 首页路由 */}
        <Route path="/" element={<Home />} />
        
        {/* 关于页面路由 */}
        <Route path="/about" element={<About />} />
        
        {/* 联系页面路由 */}
        <Route path="/contact" element={<Contact />} />
      </Routes>
    </BrowserRouter>
  );
}

2.2 创建页面组件

jsx 复制代码
// src/Home.js
function Home() {
  return <h1>首页</h1>;
}

export default Home;

// src/About.js
function About() {
  return <h1>关于我们</h1>;
}

export default About;

// src/Contact.js
function Contact() {
  return <h1>联系我们</h1>;
}

export default Contact;

三、导航链接

jsx 复制代码
import { Link } from 'react-router-dom';

function Navigation() {
  return (
    <nav>
      <Link to="/">首页</Link> |
      <Link to="/about">关于</Link> |
      <Link to="/contact">联系</Link>
    </nav>
  );
}

💡 注意:使用 Link 组件而不是 <a> 标签,因为 Link 不会重新加载页面。

3.2 导航到嵌套页面

jsx 复制代码
<Link to="/products/123">查看产品详情</Link>

四、动态路由参数

4.1 定义动态路由

jsx 复制代码
import { Routes, Route } from 'react-router-dom';
import ProductList from './ProductList';
import ProductDetail from './ProductDetail';

function App() {
  return (
    <Routes>
      <Route path="/products" element={<ProductList />} />
      {/* 动态参数 :id */}
      <Route path="/products/:id" element={<ProductDetail />} />
    </Routes>
  );
}

4.2 获取路由参数

jsx 复制代码
// src/ProductDetail.js
import { useParams } from 'react-router-dom';

function ProductDetail() {
  // 获取 URL 中的 id 参数
  const { id } = useParams();

  return (
    <div>
      <h1>产品详情</h1>
      <p>产品 ID: {id}</p>
    </div>
  );
}

export default ProductDetail;

五、嵌套路由

5.1 定义嵌套路由

jsx 复制代码
// src/App.js
import { Routes, Route } from 'react-router-dom';
import Dashboard from './Dashboard';
import Profile from './Profile';
import Settings from './Settings';

function App() {
  return (
    <Routes>
      <Route path="/dashboard" element={<Dashboard />}>
        {/* 嵌套路由 */}
        <Route path="profile" element={<Profile />} />
        <Route path="settings" element={<Settings />} />
      </Route>
    </Routes>
  );
}

5.2 使用 Outlet 渲染子路由

jsx 复制代码
// src/Dashboard.js
import { Link, Outlet } from 'react-router-dom';

function Dashboard() {
  return (
    <div>
      <h1>仪表盘</h1>
      <nav>
        <Link to="profile">个人资料</Link> |
        <Link to="settings">设置</Link>
      </nav>
      
      {/* 子路由内容将在这里渲染 */}
      <Outlet />
    </div>
  );
}

export default Dashboard;

六、路由重定向

jsx 复制代码
import { Navigate } from 'react-router-dom';

function PrivateRoute({ children, isLoggedIn }) {
  if (!isLoggedIn) {
    // 未登录时重定向到登录页
    return <Navigate to="/login" replace />;
  }
  return children;
}

// 使用
function App() {
  const isLoggedIn = false;

  return (
    <Routes>
      <Route 
        path="/dashboard" 
        element={
          <PrivateRoute isLoggedIn={isLoggedIn}>
            <Dashboard />
          </PrivateRoute>
        } 
      />
      <Route path="/login" element={<Login />} />
    </Routes>
  );
}

6.2 默认路由

jsx 复制代码
import { Navigate } from 'react-router-dom';

function App() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
      {/* 未匹配到任何路由时重定向到首页 */}
      <Route path="*" element={<Navigate to="/" />} />
    </Routes>
  );
}

七、编程式导航

7.1 使用 useNavigate Hook

jsx 复制代码
import { useNavigate } from 'react-router-dom';

function Login() {
  const navigate = useNavigate();

  const handleLogin = () => {
    // 登录成功后跳转到首页
    navigate('/');
    
    // 使用 replace 替换当前历史记录(不会返回到登录页)
    // navigate('/', { replace: true });
  };

  return <button onClick={handleLogin}>登录</button>;
}

7.2 前进和后退

jsx 复制代码
import { useNavigate } from 'react-router-dom';

function NavigationButtons() {
  const navigate = useNavigate();

  return (
    <div>
      <button onClick={() => navigate(-1)}>返回上一页</button>
      <button onClick={() => navigate(1)}>前进到下一页</button>
    </div>
  );
}

八、查询参数

8.1 获取查询参数

jsx 复制代码
import { useSearchParams } from 'react-router-dom';

function SearchResults() {
  const [searchParams] = useSearchParams();
  
  // 获取 URL 中的 query 参数
  const query = searchParams.get('q');
  const page = searchParams.get('page');

  return (
    <div>
      <h1>搜索结果</h1>
      <p>搜索关键词: {query}</p>
      <p>当前页码: {page}</p>
    </div>
  );
}

8.2 设置查询参数

jsx 复制代码
import { useSearchParams } from 'react-router-dom';

function SearchBar() {
  const [searchParams, setSearchParams] = useSearchParams();

  const handleSearch = (keyword) => {
    // 设置查询参数
    setSearchParams({ q: keyword, page: 1 });
  };

  return (
    <div>
      <input 
        type="text" 
        placeholder="搜索..."
        onChange={(e) => handleSearch(e.target.value)}
      />
    </div>
  );
}

九、实践练习

9.1 创建完整的路由应用

jsx 复制代码
// src/App.js
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';

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

function Users() {
  return (
    <div>
      <h1>用户列表</h1>
      <Link to="/users/1">用户 1</Link>
      <Link to="/users/2">用户 2</Link>
    </div>
  );
}

function UserDetail() {
  const { id } = useParams();
  return <h1>用户详情: {id}</h1>;
}

function App() {
  return (
    <BrowserRouter>
      <nav>
        <Link to="/">首页</Link> |
        <Link to="/users">用户</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/users" element={<Users />} />
        <Route path="/users/:id" element={<UserDetail />} />
      </Routes>
    </BrowserRouter>
  );
}

十、常见错误

10.1 忘记包裹 BrowserRouter

错误:

jsx 复制代码
// ❌ 没有用 BrowserRouter 包裹
function App() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
    </Routes>
  );
}

正确:

jsx 复制代码
// ✅ 使用 BrowserRouter 包裹
function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
      </Routes>
    </BrowserRouter>
  );
}

10.2 动态路由参数名称错误

错误:

jsx 复制代码
// 定义路由
<Route path="/products/:productId" element={<ProductDetail />} />

// ❌ 获取参数时名称不匹配
const { id } = useParams();  // 应该是 productId

正确:

jsx 复制代码
// ✅ 参数名称一致
const { productId } = useParams();

十一、总结与练习

11.1 本章要点

  1. ✅ 安装 react-router-dom
  2. ✅ 使用 BrowserRouter 包裹应用
  3. ✅ 使用 RoutesRoute 定义路由
  4. ✅ 使用 Link 组件实现导航
  5. ✅ 使用 useParams 获取动态路由参数
  6. ✅ 使用 useNavigate 进行编程式导航
  7. ✅ 使用 Outlet 渲染嵌套路由

11.2 课后练习

  1. 创建一个包含首页、关于页、联系页的路由应用
  2. 创建产品列表页和产品详情页,使用动态路由
  3. 实现一个登录页面,登录成功后重定向到首页
  4. 创建仪表盘页面,包含嵌套路由(个人资料、设置)

📌 系列文章导航:

  • 第一篇:React 入门前置与环境搭建
  • 第二篇:JSX 语法与组件基础
  • 第三篇:状态管理与事件处理
  • 第四篇:React Router 路由配置(当前)

相关推荐
触底反弹1 小时前
给 Claude 装上 27 个「外挂」后,我直接起飞了!
人工智能·react.js
KaMeidebaby1 小时前
卡梅德生物技术快报|peg 修饰调控 MXene/WS2 异质结,氨气传感器制备与机理研究
大数据·前端·人工智能·架构·spark·新浪微博
lichenyang4531 小时前
鸿蒙实战:安全高度 · 输入框贴键盘弹起 · Tab 底部导航全解
前端
前端毕业班1 小时前
uni-app 小程序样式隔离实践指南和原理分析
前端·javascript·vue.js
JarvanMo1 小时前
Flutter 鸿蒙化迎来"大搬家"
前端
龙佚1 小时前
抖动缓冲与播放控制:平滑播放的艺术
前端·架构
仿生狮子1 小时前
🎼 从文本到交互界面——GenUI 的中庸之道
前端·vue.js·markdown
wuhen_n2 小时前
LangChain 核心:Chain 链式调用实现复杂 AI 任务
前端·langchain·ai编程
往上跑山2 小时前
【Agentic RL / 强化学习 / OPD】OpenClaw-RL 源码阅读
前端