React 生态知识体系 / React Ecosystem Knowledge System
📅 创建时间:2026-07-28 🏷️ 标签:#React #Nextjs #StateManagement #Hooks #RSC 📚 前置知识:[[../01-javascript-and-typescript/00-overview]]
📋 本章目标
- 理解 React 在 Web 技术栈中的定位:UI 运行时 vs 应用框架
- 建立 React 生态的完整心智地图(核心 → 路由 → 状态 → 数据 → 全栈)
- 掌握 React 组件模型的核心原则(纯函数、单向数据流、声明式)
- 理解状态分类学:组件状态 vs URL 状态 vs 服务端状态 vs 全局状态
- 能够在 React + Vite(SPA)和 Next.js(全栈)之间做出合理的项目选型
- 建立"先测量,再优化"的性能思维
第1部分:React 在 Web 技术栈中的位置
1.1 React 是什么,不是什么
┌─────────────────────────────────────────────────────────────┐
│ React 的定位 │
├─────────────────────────────────────────────────────────────┤
│ │
│ React 是: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ • UI 运行时 —— 将状态映射为 UI 描述的引擎 │ │
│ │ • 组件模型 —— 封装 UI 逻辑的基本单元 │ │
│ │ • 声明式范式 —— 描述"UI 应该是什么"而非"如何做" │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ React 不是: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ • 应用框架 —— 没有内置路由、数据获取、状态管理 │ │
│ │ • SSR 解决方案 —— 需要 Next.js/Remix 等框架 │ │
│ │ • 完整的工程体系 —— 需要自行选择构建/测试/部署方案 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘1.2 React 生态全景图
┌─────────────────────────────────────────────────────────────┐
│ React 生态分层架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 全栈框架层 │ │
│ │ Next.js (App Router) / Remix / TanStack Start │ │
│ │ → SSR、RSC、文件路由、Server Actions、缓存 │ │
│ └─────────────────────────┬───────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 数据与状态层 │ │
│ │ 服务端状态:TanStack Query / RTK Query / SWR │ │
│ │ 客户端状态:Zustand / Redux Toolkit / Jotai │ │
│ │ 表单状态:React Hook Form / TanStack Form │ │
│ │ URL 状态:React Router / Next.js App Router │ │
│ └─────────────────────────┬───────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ React 核心 │ │
│ │ 组件、JSX、Props、State、Context │ │
│ │ Hooks (useState, useEffect, useReducer, useRef...) │ │
│ │ 并发特性 (Suspense, startTransition, useDeferred...)│ │
│ │ Server Components (RSC) │ │
│ └─────────────────────────┬───────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 构建与质量层 │ │
│ │ Vite / Turbopack → 开发服务器与打包 │ │
│ │ Vitest + Testing Library + Playwright → 测试 │ │
│ │ ESLint + Prettier + TypeScript → 代码质量 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘第2部分:React 核心概念速览
2.1 组件模型
┌─────────────────────────────────────────────────────────────┐
│ React 组件 = 纯函数 + 状态 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 组件签名:Props → JSX │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ function Welcome({ name }: { name: string }) { │ │
│ │ return <h1>Hello, {name}</h1> │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 核心约束: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 1. 渲染必须保持纯净:相同 Props + State + Context │ │
│ │ → 相同 JSX │ │
│ │ 2. 渲染期间不得修改外部变量、发请求或操作 DOM │ │
│ │ 3. Props 是只读的 —— 子组件不能修改 Props │ │
│ │ 4. State 是一次渲染的快照 —— setState 请求下次渲染 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 渲染 ≠ DOM 更新: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Render(计算新 JSX)→ Reconcile(对比新旧)→ │ │
│ │ Commit(仅更新变化的 DOM) │ │
│ │ 组件被调用 ≠ 对应的 DOM 节点一定被修改 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘2.2 Hooks 速览
┌─────────────────────────────────────────────────────────────┐
│ React Hooks 分类 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 状态 Hooks: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ useState → 组件级状态 │ │
│ │ useReducer → 复杂状态转换逻辑 │ │
│ │ useRef → 可变引用(不触发渲染) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 副作用 Hooks: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ useEffect → 同步外部系统 │ │
│ │ useLayoutEffect→ DOM 更新后、浏览器绘制前 │ │
│ │ useInsertionEffect → CSS-in-JS 库专用 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 性能 Hooks: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ useMemo → 缓存计算结果 │ │
│ │ useCallback → 缓存函数引用 │ │
│ │ useTransition → 标记非紧急更新 │ │
│ │ useDeferredValue → 延迟更新值 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 其他关键 Hooks: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ useContext → 消费 Context │ │
│ │ useId → 生成唯一 ID(SSR 安全) │ │
│ │ useSyncExternalStore→ 订阅外部状态 │ │
│ │ useImperativeHandle → 自定义 ref 暴露的方法 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘第3部分:状态分类学
3.1 四种状态,四种管理方式
┌─────────────────────────────────────────────────────────────┐
│ 状态分类学 │
├─────────────────────────────────────────────────────────────┤
│ │
│ │ 状态类型 │ 生命周期 │ 推荐方案 │
│ ├──────────────┼──────────────────┼──────────────────────┤
│ │ 组件交互状态 │ 组件挂载期间 │ useState/useReducer │
│ │ │ 随组件卸载销毁 │ │
│ ├──────────────┼──────────────────┼──────────────────────┤
│ │ URL 状态 │ 浏览器历史记录 │ React Router / │
│ │ │ 可分享/可回退 │ Next.js App Router │
│ ├──────────────┼──────────────────┼──────────────────────┤
│ │ 服务端状态 │ 以服务器为准 │ TanStack Query / │
│ │ │ 需要缓存/同步 │ RTK Query / SWR │
│ ├──────────────┼──────────────────┼──────────────────────┤
│ │ 客户端全局 │ 跨页面/跨组件 │ Zustand / │
│ │ 业务状态 │ 应用存活期间 │ Redux Toolkit │
│ ├──────────────┼──────────────────┼──────────────────────┤
│ │ 表单草稿 │ 填写期间 │ React Hook Form / │
│ │ │ 提交后转为服务端 │ TanStack Form │
│ │
│ ⚠️ 常见反模式:把所有数据都放入全局 Store │
│ 正确的做法:先问"这个数据的生命周期是多长?"再决定放哪 │
│ │
└─────────────────────────────────────────────────────────────┘3.2 状态方案选型决策树
┌─────────────────────────────────────────────────────────────┐
│ 状态管理选型决策树 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 这个状态... │
│ │ │
│ ├── 只在一个组件内使用? → useState │
│ │ │
│ ├── 需要被几个紧密相关的组件共享? → Context + │
│ │ useReducer(不要过早引入外部 Store) │
│ │ │
│ ├── 需要跨很多不相关的组件共享? │
│ │ ├── 数据来自服务器? → TanStack Query │
│ │ └── 纯客户端数据? │
│ │ ├── 体积小/简单? → Zustand │
│ │ └── 复杂/需可审计? → Redux Toolkit │
│ │ │
│ ├── 是表单数据? → React Hook Form + Zod │
│ │ │
│ └── 用户应该能分享/收藏? → URL 参数 │
│ │
└─────────────────────────────────────────────────────────────┘第4部分:React SPA vs Next.js 全栈
4.1 两种架构对比
┌─────────────────────────────────────────────────────────────┐
│ SPA vs 全栈架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ React SPA (Vite + React Router): │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 浏览器 服务器 │ │
│ │ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ React App │ ←── JSON ──→ │ REST API │ │ │
│ │ │ (纯客户端) │ │ (任意后端) │ │ │
│ │ └─────────────┘ └─────────────┘ │ │
│ │ │ │
│ │ 优点:前后端分离、任意后端语言、部署简单 │ │
│ │ 缺点:SEO 差、首屏白屏、JS 体积大 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Next.js 全栈: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 浏览器 Next.js │ │
│ │ ┌─────────────┐ ┌───────────────────────────┐ │ │
│ │ │ Client │ │ Server Components (RSC) │ │ │
│ │ │ Components │ ←→ │ Route Handlers │ │ │
│ │ │ (交互) │ │ Server Actions │ │ │
│ │ └─────────────┘ │ → DB / Redis / External API│ │ │
│ │ └───────────────────────────┘ │ │
│ │ │ │
│ │ 优点:SEO、首屏 SSR、类型安全端到端、一体化部署 │ │
│ │ 缺点:绑定 Vercel/Node.js、学习曲线陡、调试复杂 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘4.2 选型决策
| 场景 | 推荐 | 原因 |
|---|---|---|
| 内部管理后台(无需 SEO) | React + Vite | 简单直接,部署灵活 |
| 需要嵌套路由的 SPA | React Router | 路由是客户端核心状态 |
| 内容网站(需要 SEO) | Next.js | SSR/SSG 开箱即用 |
| 电商/SaaS(SEO + 交互密集) | Next.js | RSC + Client 组合 |
| 快速原型验证 | React + Vite | 最少配置,最快启动 |
| 大型企业全栈项目 | Next.js | 统一前端 + BFF 层 |
第5部分:本模块文章导航
┌─────────────────────────────────────────────────────────────┐
│ React 模块文章导航 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ [本文] 00-overview — React 生态全景与学习路线 │ │
│ └─────────────────────────┬───────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 01-react-components-and-rendering │ │
│ │ • 渲染/协调/提交三阶段 • Fiber 架构 • 并发特性 │ │
│ │ • Props/State/Key • memo/useMemo/useCallback │ │
│ └─────────────────────────┬───────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 02-hooks-state-and-effects │ │
│ │ • useState/useReducer/useRef │ │
│ │ • useEffect/useLayoutEffect │ │
│ │ • 自定义 Hook 设计模式 • React 19 新 Hooks │ │
│ └─────────────────────────┬───────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 03-routing-forms-and-component-architecture │ │
│ │ 04-redux-zustand-state-management │ │
│ └─────────────────────────┬───────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 05-nextjs-app-router-and-rendering │ │
│ │ 06-nextjs-data-cache-mutations │ │
│ │ 07-tanstack-query-server-state │ │
│ │ 08-testing-performance-production │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘核心总结
总结1:React 不是框架,是 UI 运行时
React 只负责"将状态转换为 UI 描述"这一件事。路由、数据获取、状态管理、构建、部署——都需要从生态中选择。这也是为什么 React 生态如此丰富但也容易让新手迷失——因为"自由选择"的另一面是"必须选择"。
总结2:状态分类是 React 工程化的第一课
不要把 URL 参数存入 Redux,不要把服务端响应存入 useState,不要把表单草稿存入 URL。理解每种状态的生命周期和所有者,是避免 React 项目中状态混乱的第一步。
总结3:先测量,再优化
React 的 memo/useMemo/useCallback 不是"默认就加"的东西——它们有自己的内存和比较开销。使用 React DevTools Profiler 找出真正的性能瓶颈,再决定优化策略。
章节测试
测试1:React 的渲染(Render)和 DOM 更新(Commit)是什么关系?
A. Render 就是更新 DOM B. Render 计算新 JSX → Reconcile 对比新旧 → Commit 更新变化的 DOM C. Commit 发生在 Render 之前 D. 它们是同一个步骤的不同名称
测试2:以下哪个状态应该放在 URL 中而不是 Redux/Zustand 中?
A. 当前登录用户信息 B. 搜索关键词和筛选条件(用户希望能分享搜索结果) C. 表单填写草稿 D. 从 API 获取的产品列表
测试3:以下哪个不是 React 官方 Hook?
A. useState B. useReducer C. useFetch D. useDeferredValue
测试4:React Server Components (RSC) 的关键限制是什么?
A. 不能使用 TypeScript B. 不能包含交互逻辑(useState/useEffect/事件处理) C. 不能渲染 HTML D. 不能在服务端执行数据库查询
测试5:简述 React SPA 和 Next.js 全栈各适合什么场景?
参考答案
测试1答案
答案:B。一次更新分为三个阶段:Render(调用组件函数计算新 JSX)、Reconcile(React 内部按类型和 key 对比新旧元素树)、Commit(将确实变化的节点应用到 DOM)。组件被调用不代表对应 DOM 一定改变。
测试2答案
答案:B。搜索关键词和筛选条件应该放在 URL 中,因为用户可能想要分享、收藏或通过浏览器后退按钮回到之前的筛选状态。其他选项各有归属:用户信息 → Context/Zustand、表单草稿 → 组件状态/React Hook Form、产品列表 → TanStack Query。
测试3答案
答案:C。useFetch 不是 React 官方 Hook。数据获取在 React 中通常通过 TanStack Query、SWR 等库实现,或者使用 React 19 的新 use() hook。自己封装 useFetch 是常见的自定义 Hook 练习,但 React 核心没有内置它。
测试4答案
答案:B。Server Components 在服务端运行,不能包含交互逻辑——不能使用 useState、useEffect、onClick 等浏览器端的能力。它们是专门用于可序列化的数据获取和渲染的。交互逻辑必须放在标记了 'use client' 的 Client Components 中。
测试5答案
React SPA(Vite + React Router) 适合:内部管理后台、不需要 SEO 的应用、前后端分离架构、团队想要任意后端语言、快速原型的场景。 Next.js 全栈 适合:需要 SEO 的内容网站、电商/SaaS 等需要 SSR 的应用、希望全栈 TypeScript 类型安全的项目、需要在服务端执行数据获取和渲染的场景。
相关笔记
- [[01-react-components-and-rendering]] — 组件渲染深度
- [[02-hooks-state-and-effects]] — Hooks 完整指南
- [[04-redux-zustand-state-management]] — 状态管理方案对比
- [[../01-javascript-and-typescript/00-overview]] — JS/TS 基础知识
下一步学习
- [ ] 阅读 React 组件、渲染与数据流 — 理解 Fiber 与并发
- [ ] 写一个不含任何状态管理库的 React 应用,仅用 Context + useReducer
- [ ] 对比 React SPA 和 Next.js 应用的首屏加载时间
学习状态:🟡 开始学习