React 生态
React Router
React Router 是 React 生态中最流行的路由解决方案,它提供了一套声明式的路由管理机制,让单页应用(SPA)的页面导航变得直观且高效。
核心组件
BrowserRouter 是 React Router 的根组件,它使用 HTML5 History API 来保持 UI 与 URL 的同步。它将历史记录栈抽象化,使得前进、后退等浏览器原生行为能够在 SPA 中正常工作。与之类似的还有 HashRouter,它使用 URL 的 hash 部分来管理路由状态。
Routes 和 Route 是路由配置的核心。Routes 组件负责匹配当前 URL 并渲染对应的 Route 组件。每个 Route 通过 path 属性定义匹配模式,通过 element 属性指定要渲染的组件:
import { BrowserRouter, Routes, Route } from 'react-router-dom'
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/blog/:slug" element={<Article />} />
</Routes>
</BrowserRouter>
)
}常用 Hooks
useParams 用于从当前路由中提取动态参数。在上面的例子中,/blog/:slug 匹配到 /blog/hello-world 后,useParams 会返回 v-pre`。这在构建详情页时非常有用。
useNavigate 提供了编程式导航的能力。与声明式的 <Link> 组件不同,useNavigate 允许你在事件处理函数、副作用或条件逻辑中触发页面跳转:
function LoginButton() {
const navigate = useNavigate()
function handleLogin() {
// 登录逻辑...
navigate('/dashboard', { replace: true })
}
return <button onClick={handleLogin}>登录</button>
}嵌套路由
嵌套路由是 React Router 组织复杂页面结构的重要能力。通过嵌套 Route,你可以让父布局组件包裹子页面,实现导航栏、侧边栏等共享 UI 的持久化:
<Route path="/dashboard" element={<DashboardLayout />}>
<Route index element={<Overview />} />
<Route path="settings" element={<Settings />} />
<Route path="users" element={<Users />} />
</Route>在上面的配置中,DashboardLayout 组件通过 <Outlet /> 占位符来渲染匹配的子路由,这种模式天然支持布局复用。
路由守卫
路由守卫用于控制页面的访问权限。在 React Router 中,可以通过封装一个 ProtectedRoute 组件来实现:
function ProtectedRoute({ children }) {
const token = useAuth() // 自定义认证 Hook
const navigate = useNavigate()
useEffect(() => {
if (!token) {
navigate('/login', { replace: true })
}
}, [token, navigate])
return token ? children : null
}这种方式将认证逻辑与页面组件解耦,当用户未登录时自动跳转到登录页,同时保留原始目标路径以便登录后回跳。
Next.js
Next.js 是由 Vercel 维护的 React 元框架,它提供了生产级 Web 应用所需的全套能力,包括路由、渲染策略、API 接口和构建优化。
文件路由系统
Next.js 使用文件系统作为路由的定义方式。在 App Router 模式下,app/ 目录下的文件夹结构直接映射为 URL 路径:
app/
├── page.js → /
├── layout.js → 根布局
├── blog/
│ ├── page.js → /blog
│ └── [slug]/
│ └── page.js → /blog/:slug每个路由目录可以包含 page.js(页面)、layout.js(布局)、loading.js(加载态)、error.js(错误边界)等特殊文件,这些文件共同定义了该路由的行为。
渲染策略
服务端渲染(SSR):每次请求时在服务器上生成完整的 HTML,确保用户看到的是完整内容,有利于 SEO 和首屏性能。Next.js 默认的 App Router 组件就是服务端组件。
静态站点生成(SSG):在构建时预生成 HTML 页面,适用于内容变化不频繁的场景。通过 generateStaticParams 函数可以为动态路由预生成所有可能路径:
export async function generateStaticParams() {
const posts = await fetch('https://api.example.com/posts').then(r => r.json())
return posts.map(post => ({ slug: post.slug }))
}增量静态再生(ISR):结合了 SSG 的速度和动态数据的实时性。通过设置 revalidate 选项,页面会在请求时检查缓存是否过期,若过期则在后台重新生成:
export const revalidate = 3600 // 每小时重新验证Next.js 14+ 还支持按需 ISR,通过 API 路由或 Webhook 精确触发指定页面的重新生成。
API Routes
Next.js 允许在同一项目中构建 API 端点。在 App Router 中,通过 route.js 文件定义:
// app/api/posts/route.js
export async function GET() {
const posts = await db.query('SELECT * FROM posts')
return Response.json(posts)
}API Routes 支持 GET、POST、PUT、DELETE 等 HTTP 方法,且自动支持边缘运行时。
Middleware
Next.js Middleware 在请求到达页面之前执行,运行在 Edge Runtime 中。它适用于认证守卫、重定向、A/B 测试和国际化等场景:
// middleware.js
import { NextResponse } from 'next/server'
export function middleware(request) {
const token = request.cookies.get('token')
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url))
}
return NextResponse.next()
}
export const config = {
matcher: ['/dashboard/:path*']
}Server Components
React Server Components(RSC)是 React 18 引入的架构变革,它重新定义了组件在客户端和服务端的职责边界。
RSC 核心概念
RSC 允许组件在服务端运行,直接访问数据库、文件系统等后端资源,并将渲染结果以特殊格式序列化后发送到客户端。这带来了两个根本性变化:
- 零客户端体积:服务端组件的代码不会发送到浏览器,其依赖的库(如 marked、moment 等)也不包含在打包文件中。
- 直接数据访问:服务端组件可以直接执行数据库查询、读取文件,无需构建 API 端点。
客户端 vs 服务端组件
默认情况下,Next.js App Router 中的所有组件都是服务端组件。当需要使用交互能力时,才需要在文件顶部添加 "use client" 指令:
| 特征 | 服务端组件 | 客户端组件 |
|---|---|---|
| 状态管理 | 不支持 | 支持 useState/useReducer |
| 副作用 | 不支持 | 支持 useEffect |
| 事件处理 | 不支持 | 支持 onClick 等 |
| 数据获取 | 直接访问后端 | 通过 API 或客户端请求 |
| JavaScript 体积 | 零 | 包含在打包文件中 |
流式渲染
流式渲染(Streaming)是 RSC 的重要能力之一。服务端可以分批发送渲染结果,客户端逐步呈现。这意味着你可以在数据完全加载之前就开始展示页面内容,显著改善用户体验。
Next.js 通过 loading.js 和 React Suspense 实现流式渲染。Suspense 边界内的组件会独立流式传输,先完成的先展示。
React 元框架对比
除了 Next.js,React 生态中还有多个优秀的元框架,各有侧重。
Next.js
Vercel 出品,功能最为全面的 React 元框架。优势在于丰富的渲染策略(SSR/SSG/ISR)、成熟的生态系统和强大的边缘网络支持。适合从内容网站到企业级应用的各种场景。
Remix
由 React Router 团队创建,强调 Web 标准和渐进式增强。Remix 使用嵌套路由模型,每个路由模块可以独立管理其数据加载(loader)和提交(action)。它对表单处理和乐观更新有天然支持,适合数据密集型应用。
Gatsby
以静态站点生成为核心的框架,拥有庞大的插件生态。Gatsby 通过 GraphQL 层统一数据源管理,在构建时预先生成所有页面。它适合内容型网站和博客,但在动态交互场景下需要额外的配置。
Astro
Astro 采用创新的 "岛屿架构"(Islands Architecture),默认输出零 JavaScript 的静态 HTML,只在需要交互的组件上加载 JS。它支持多框架混用(React、Vue、Svelte 等),适合内容优先的网站。
| 框架 | 渲染方式 | 适用场景 | 特点 |
|---|---|---|---|
| Next.js | SSR/SSG/ISR | 通用应用 | 最全面的功能集 |
| Remix | SSR | 数据密集型应用 | Web 标准、嵌套路由 |
| Gatsby | SSG | 内容网站、博客 | 丰富的插件生态 |
| Astro | SSG + 岛屿 | 内容优先网站 | 多框架支持、零 JS 默认 |
开发工具链
React 项目从开发到生产需要一套完整的工具链支持。
Vite
Vite 是目前最受欢迎的构建工具之一。它利用原生 ES 模块(ESM)在开发环境下实现极速冷启动,通过 esbuild 进行预构建,在生产构建时则使用 Rollup 进行打包优化。Vite 开箱即支持 TypeScript、JSX、CSS Modules 等特性。
Webpack
Webpack 是传统上最主流的打包工具,拥有丰富的 loader 和 plugin 生态。虽然配置相对复杂,但其高度可定制性和成熟的社区支持使其在大型项目中仍有广泛应用。
esbuild
esbuild 使用 Go 语言编写,打包速度极快(比传统工具快 10-100 倍)。它通常作为 Vite 和 Turbopack 的底层引擎使用,也可以直接作为构建工具用于简单项目。
Babel 配置
Babel 是 JavaScript 编译器,用于将现代 JSX/TypeScript 代码转换为兼容性更好的目标代码。典型的 React Babel 配置:
{
"presets": [
["@babel/preset-env", { "targets": "> 0.25%, not dead" }],
["@babel/preset-react", { "runtime": "automatic" }],
"@babel/preset-typescript"
]
}其中 @babel/preset-react 的 runtime: "automatic" 模式会自动引入 React JSX 转换函数,无需在每个文件中显式导入 React。
测试工具
测试是保障 React 应用质量的关键环节,从单元测试到端到端测试,需要合理的测试分层。
Jest
Jest 是 React 生态中最常用的测试运行器和断言库。它提供了零配置的开箱体验、快照测试、覆盖率收集和模拟功能。Jest 通常与 React Testing Library 配合使用。
React Testing Library
React Testing Library 是 React 组件测试的事实标准。它鼓励从用户视角测试组件——关注组件的输出行为而非实现细节。核心原则是:你越接近用户使用组件的方式,测试就越有价值。
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
test('点击按钮后显示欢迎信息', async () => {
render(<Welcome name="张三" />)
const button = screen.getByRole('button', { name: /点击我/i })
await userEvent.click(button)
expect(screen.getByText('你好,张三!')).toBeInTheDocument()
})Cypress
Cypress 是面向开发者的端到端测试框架。它的优势在于时间旅行调试(每一步操作都可以回放)、自动等待(无需手动添加等待时间)和实时重载。Cypress 还支持组件测试和 API 测试。
Playwright
Playwright 是微软开发的跨浏览器自动化测试工具。它支持 Chromium、Firefox 和 WebKit 三大浏览器引擎,以及移动端浏览器模拟。Playwright 提供了强大的网络拦截、文件下载和多页面/多标签页测试能力。
| 工具 | 测试层次 | 主要优势 |
|---|---|---|
| Jest + RTL | 单元/集成测试 | 组件行为验证、DOM 交互模拟 |
| Cypress | 端到端测试 | 时间旅行调试、实时重载 |
| Playwright | 端到端测试 | 多浏览器支持、跨平台自动化 |
选择测试工具时,建议遵循测试金字塔原则:大量低成本的单元测试、适量的集成测试和少量的端到端测试,以最小的维护成本获得最大的质量保障。