从0 死磕全栈第3天:React Router (Vite + React + TS 版):构建小时站实战指南

导语 :未拆封的信笺躺在抽屉深处,如同未被唤起的往事------直到某天风吹动门扉,那些字句突然开始呼吸。技术亦是如此,从一个 Hello World 开始,构建你的全栈世界。

本文将带你使用 Vite + React + TypeScript 作为技术栈,从零开始学习 react-router-dom,并通过构建一个名为"小时站"的精炼项目来实践所学知识。


一、环境准备

1. 使用 Vite 创建 React-TS 项目

打开终端,执行以下命令:

bash 复制代码
# 创建项目
npm create vite@latest hour-station -- --template react-ts

# 进入项目
cd hour-station

# 安装依赖
npm install

# 安装路由库
npm install react-router-dom @types/react-router-dom

# 启动开发服务器
npm run dev

2. 初始化项目结构

创建以下目录和文件:

css 复制代码
src/
├── pages/
│   ├── Home.tsx
│   ├── About.tsx
│   ├── Contact.tsx
│   └── User.tsx
├── App.tsx
├── main.tsx
└── vite-env.d.ts

二、基础路由实现

1. 修改 App.tsx

这是应用的主组件,负责定义路由导航和路由出口。

tsx 复制代码
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';
import Contact from './pages/Contact';

function App() {
  return (
    <Router>
      <nav style={{ padding: '10px', background: '#f0f0f0' }}>
        <Link style={{ margin: '0 10px' }} to="/">首页</Link>
        <Link style={{ margin: '0 10px' }} to="/about">关于</Link>
        <Link style={{ margin: '0 10px' }} to="/contact">联系</Link>
      </nav>
      <div style={{ padding: '20px' }}>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
          <Route path="/contact" element={<Contact />} />
        </Routes>
      </div>
    </Router>
  );
}

export default App;

核心概念

  • BrowserRouter:提供基于 HTML5 History API 的路由。
  • Routes:包含所有 Route 的容器。
  • Route:定义路径(path)与对应组件(element)的映射。
  • Link:用于导航的声明式组件,避免页面刷新。

React 的核心思想是组件化 ,它把 UI 看作是由一个或多个组件组合而成。App.tsxHome.tsxAbout.tsx 都是独立的组件。

2. 创建页面组件 (TypeScript 版)

pages/Home.tsx

tsx 复制代码
export default function Home() {
  return (
    <div>
      <h1>欢迎来到小时站</h1>
      <p>这是一个使用 Vite + React + TypeScript 构建的示例项目</p>
    </div>
  );
}

关于 TSX

  • JSX 是 JavaScript 的语法扩展,允许在 JS 中编写类似 HTML 的标记,用于描述 UI 结构。
  • TSXJSX 的 TypeScript 版本,在 JSX 基础上增加了静态类型检查,适用于 TypeScript 项目。

pages/About.tsx

tsx 复制代码
export default function About() {
  return <h1>关于我们</h1>;
}

pages/Contact.tsx

tsx 复制代码
export default function Contact() {
  return <h1>联系我们</h1>;
}

三、进阶功能实现

1. 动态路由

实现 /user/123/user/456 等路径,其中 123456 是动态的用户 ID。

pages/User.tsx

tsx 复制代码
import { useParams } from 'react-router-dom';

interface UserParams {
  id: string;
}

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

更新 App.tsx 路由配置

tsx 复制代码
import User from './pages/User';

// 在 <Routes> 中添加
<Route path="/user/:id" element={<User />} />

:id 是一个路由参数,可以通过 useParams() Hook 获取。


2. 嵌套路由 (TypeScript 版)

在"关于"页面下,创建"团队"和"历史"两个子页面。

重构 pages/About.tsx

tsx 复制代码
import { Routes, Route, Link, Outlet } from 'react-router-dom';

export default function About() {
  return (
    <div>
      <h1>关于我们</h1>
      <nav style={{ margin: '10px 0' }}>
        <Link style={{ margin: '0 10px' }} to="team">团队</Link>
        <Link style={{ margin: '0 10px' }} to="history">历史</Link>
      </nav>
      <Outlet /> {/* 子路由组件的渲染位置 */}
    </div>
  );
}

// 导出子组件
export function Team() {
  return <h2>我们的团队</h2>;
}

export function History() {
  return <h2>发展历史</h2>;
}

更新 App.tsx

tsx 复制代码
import About, { Team, History } from './pages/About';

// 修改 About 路由,添加子路由
<Route path="/about" element={<About />}>
  <Route path="team" element={<Team />} />
  <Route path="history" element={<History />} />
</Route>

Outlet 组件是父路由中用于渲染其子路由的占位符。


四、完整"小时站"实现

1. 完整 App.tsx

tsx 复制代码
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import Home from './pages/Home';
import About, { Team, History } from './pages/About';
import Contact from './pages/Contact';
import User from './pages/User';

function App() {
  return (
    <Router>
      <nav
        style={{
          padding: '10px',
          background: '#f0f0f0',
          display: 'flex',
          gap: '10px'
        }}
      >
        <Link to="/">首页</Link>
        <Link to="/about">关于</Link>
        <Link to="/contact">联系</Link>
        <Link to="/user/123">示例用户</Link>
      </nav>
      <div style={{ padding: '20px' }}>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />}>
            <Route path="team" element={<Team />} />
            <Route path="history" element={<History />} />
          </Route>
          <Route path="/contact" element={<Contact />} />
          <Route path="/user/:id" element={<User />} />
        </Routes>
      </div>
    </Router>
  );
}

export default App;

2. 增强版 Home.tsx (带 TypeScript 类型)

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

interface UserLink {
  id: string;
  name: string;
}

export default function Home() {
  const users: UserLink[] = [
    { id: '1', name: '用户一' },
    { id: '2', name: '用户二' },
    { id: '3', name: '用户三' }
  ];

  return (
    <div>
      <h1>欢迎来到小时站</h1>
      <p>这是一个使用 Vite + React + TypeScript 构建的示例项目</p>
      <div style={{ marginTop: '20px' }}>
        <h3>热门用户</h3>
        <ul style={{ listStyle: 'none', padding: 0 }}>
          {users.map(user => (
            <li key={user.id} style={{ margin: '5px 0' }}>
              <Link to={`/user/${user.id}`}>{user.name}</Link>
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
}

五、TypeScript 进阶技巧

1. 自定义路由类型

创建 types/router.d.ts 文件,定义可复用的类型。

ts 复制代码
import { ReactNode } from 'react';

export interface RouteItem {
  path: string;
  element: ReactNode;
  children?: RouteItem[];
}

export interface UserParams {
  id: string;
}

2. 使用 useNavigate 进行编程式导航

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

function UserActions() {
  const navigate = useNavigate();
  const handleClick = (userId: string) => {
    navigate(`/user/${userId}`);
  };

  return (
    <button onClick={() => handleClick('123')}>
      查看用户
    </button>
  );
}

总结

恭喜!你已经成功构建了一个功能完整的 React 应用。

通过本次实践,你掌握了:

  • ✅ 使用 Vite 快速搭建 React + TypeScript 开发环境
  • react-router-dom 的核心概念:BrowserRouterRoutesRouteLinkOutlet
  • ✅ 动态路由 (:id) 与嵌套路由的实现
  • ✅ 在 TypeScript 中为路由参数和组件定义类型
相关推荐
吃饺子不吃馅16 小时前
AntV X6 核心插件帮你飞速创建画布
前端·css·svg
葡萄城技术团队16 小时前
SpreadJS 纯前端表格控件:破解中国式复杂报表技术文档
前端
Humbunklung16 小时前
C# 压缩解压文件的常用方法
前端·c#·压缩解压
通往曙光的路上16 小时前
时隔一天第二阶段他来了 html!!!!!!!!!!!
前端·html
爱吃甜品的糯米团子16 小时前
CSS图片背景属性
前端·css
雮尘16 小时前
一文读懂Android Fragment栈管理
android·前端
Aoda17 小时前
浏览器字体设置引发的Bug:从一次调查到前端字体策略的深度思考
前端·css
朝与暮17 小时前
《javascript进阶-类(class):构造函数的语法糖》
前端·javascript
入秋17 小时前
Three.js 实战之电子围栏可根据模型自动生成
前端·前端框架·three.js
用户61204149221317 小时前
jsp+servlet做的咖啡品牌管理后台
java·前端·后端