本节摘要:React 由 Meta(原 Facebook)维护,是"库级定位 + 生态霸权"的典型。它以声明式 UI、组件化、虚拟 DOM、单向数据流与 JSX 五大特性成为大型 SPA 与跨平台开发的主流选择,但"只负责 UI"的定位也意味着路由、状态、请求都要自己拼装。本节拆解它的核心机制、生态版图与真实代价,帮你判断"自由"是资产还是负担。
阅读完本节,你应当能够:
2023 年前后打开任何一份"前端框架使用率"报告,React 几乎都是榜首。但有意思的是,React 官方文档的第一句话是:"用于构建 Web 和原生交互界面的库。"它自称"库",不是"框架"。
这种定位带来了一个真实的两难:一方面,你几乎可以在 React 生态里找到任何你想要的东西——路由有 React Router,状态管理有 Redux/MobX/Zustand/Recoil,UI 库有 Ant Design/MUI/Chakra;另一方面,选择太多本身就是成本。新手最容易问的问题不是"怎么写",而是"我该用哪个"。
本节想帮你建立的直觉是:React 的强项是"组合的自由",弱项也是"组合的自由"。它像乐高,什么都能搭,但搭什么、怎么搭,责任在你。
命令式代码要你一步步告诉浏览器"先创建元素、再设内容、再挂载";声明式代码只描述"在给定状态下,UI 应该长什么样"。
// 声明式:只描述最终状态 function Greeting(props) { return <h1>Hello, {props.name}!</h1>; }
数据变化时,React 自动负责把 UI 更新到与数据一致。这让代码可预测、易调试——你不再需要跟踪每一次 DOM 操作。
应用被拆成独立、可复用的组件,通过 props 传数据、state 管内部状态。函数组件(配合 Hooks)如今是主流写法,类组件逐渐退居存量代码。组件化的收益在第 1 章讲过,这里只说 React 的特色:组件边界就是数据流的边界,单向数据流让"数据从哪来到哪去"一目了然。
虚拟 DOM 解决"减少真实 DOM 操作",Fiber 解决"不要让一次大更新卡死主线程"。
React.createElement() 调用。| 方向 | 代表方案 | 用途 |
|---|---|---|
| 状态管理 | Redux、MobX、Zustand、Recoil | 跨组件共享状态 |
| 路由 | React Router | 客户端路由 |
| UI 组件库 | Ant Design、Material-UI、Chakra UI | 快速搭建界面 |
| 测试 | Jest、React Testing Library | 单元与集成测试 |
| SSR/SSG | Next.js、Gatsby | 服务端渲染与静态生成 |
| 移动端 | React Native | 原生移动应用 |

| 维度 | React 的表现 | 代价 |
|---|---|---|
| 灵活度 | 极高,自由拼装 | 选择负担大,方案五花八门 |
| 学习曲线 | 初期平缓、后期陡峭 | 要理解 Hooks 心智、虚拟 DOM、性能优化 |
| 构建工具 | Webpack/Vite 等自由选 | 初次配置可能繁琐 |
| 状态管理 | 多方案并存 | 团队要统一规范,否则风格混乱 |
| 完整度 | 库级,缺啥补啥 | 相对 Angular 无"开箱即用全家桶" |
⚠️ 常见坑:团队刚上手就铺开 Redux + Saga + 一堆中间件,把简单应用复杂化。小到中型应用,Zustand 或 React 自带 Context 往往就够用。选型同样适用于"库的选型"。
💡 关键直觉:把 React 想象成工具箱而非成品的家。箱子里什么都有,但"装成什么样"完全取决于你的手艺和规范——这也是为什么 React 项目之间的代码风格能差出十万八千里。
既然 React 的自由是双刃剑,那成熟团队的做法是"用规范把自由关进笼子"。给你一份可落地的清单:第一,状态管理选一个主力方案并写进文档,别让每个模块各用各的——小项目 Zustand、大项目 Redux Toolkit 是当前比较稳的两条路。第二,目录结构约定好"页面/组件/服务/hooks"分层,避免团队各自造轮子。第三,性能优化的纪律要前置:什么情况下必须用 memo、useMemo、useCallback,什么情况下禁止用(它们本身有成本),写清楚比事后救火有效。第四,代码风格统一交给 ESLint + Prettier,提交前强制过一遍。这套规范不复杂,但能解决 React 项目 80% 的"风格灾难"。
React 的演进史本身就是一部"框架怎么做大决策"的教科书:16 引入 Fiber 重写调度,16.8 引入 Hooks 改变组件写法,18 引入并发特性(如 useTransition、startTransition)为渲染让路。这些变化方向一致——都在让"大应用在复杂更新下保持流畅"成为可能。对选型的启示是:一个框架如果持续围绕"规模化问题"做架构级更新,说明它的维护方在认真押注长期;反之,如果版本号升得勤但都是小修小补,你就要多留一分警惕。判断"更新质量"而非"更新频率",是第 3 章维护性维度的核心思路,这里先用 React 给个范例。
存量 React 项目里仍能听到"函数组件 vs 类组件"的争论,值得用一句话终结:新代码一律函数组件 + Hooks,老代码逐步迁移,不必强求一次改完。理由很实际:类组件的 this 绑定、生命周期方法的语义纠缠让逻辑复用困难;函数组件配合 Hooks 把"逻辑按功能分组"变成了可能(自定义 Hook 就是把一段状态逻辑抽出来复用)。唯一需要留意的坑是:在给老组件加 Hooks 时,要确认它没有依赖类组件的 componentDidCatch 这类类独有能力——错误边界目前仍以类组件形式为主。把这场争论内部消化掉,团队才能在选型讨论里把精力留给真正重要的问题:这个项目要不要用 React 的哪个生态位,而不是要不要拥抱 Hooks。
React 起步时 JavaScript 是唯一选项,TypeScript 只是可选的"加钱项";但今天再评估 React,几乎应该默认"TypeScript + React"的组合。原因很实际:props 的类型注解让"子组件该传什么"变成编译器能检查的契约,大型组件树里这省掉的排查时间是实打实的;配合工具链(tsconfig 严格模式),很多运行时错误被提前到编译期。当然要承认代价:引入类型系统有学习成本,且与第三方库的 @types 兼容偶尔会踩坑。我们的判断是:新项目直接 TS,老项目在可行时渐进引入——与"函数组件"那节的结论一致,方向都是"向更可维护的形态收敛"。这条也适用于 Vue 3 与 Angular(后者本就强制 TS)。把"要不要 TS"从"可选争议"变成"默认前提",你的 React 选型讨论会干净很多。
React 生态近年最值得关注的架构变化,是 Next.js 带火的 React Server Components(RSC)——把一部分组件放到服务端执行,只把渲染结果发到客户端,从而减少发往浏览器的 JavaScript。对选型者的实际含义是:如果你的项目以 SSR 为主、又有大量纯展示组件,RSC 能明显压缩客户端 JS 体积;但如果你的应用偏重客户端交互、实时状态多,RSC 能捞到的好处就有限,反而增加"哪个组件在服务端、哪个在客户端"的认知负担。建议是:默认先不用,等确实遇到"客户端 JS 太大"的痛点,再按页面逐个迁移到 RSC。任何新架构特性,都应遵循"痛点驱动采用",而不是"潮流驱动采用"——这条原则贯穿第 3 章的维护性维度与第 4 章的风险评估。
面对 React 的庞大生态,新手最常问"我该从哪下手"。给你一个按优先级排序的答案:第一优先是脚手架(Vite 或官方推荐模板)——先把"项目能跑"这件事稳定下来;第二优先是状态管理(小项目用内置状态 + Zustand,大项目 Redux Toolkit)——这是多数 React 项目最痛的一块;第三优先是路由(React Router)与请求方案(基于 fetch 封装一层即可);第四优先才是 UI 组件库与样式方案。这个顺序的依据是"痛点频率":状态混乱导致的返工,比"样式不够好看"昂贵得多。记住一个原则:React 生态不是"全部都要选",而是"每个痛点选一个、非痛点不选"——克制,才是 React 选型里最稀缺的能力。
这个优先级还有一个隐藏价值:它帮你把"生态选择"从无限选项压缩成有限决策。React 生态最大的敌人不是缺少方案,而是方案太多导致的精神内耗——每多一个自由度,团队就要多花一份讨论成本。用"痛点驱动"而不是"看到就装",你既享受生态的丰富,又不被丰富本身淹没。
下一节看 Vue:它如何用"渐进式"把 React 的自由和 Angular 的完整折中到一条平滑斜坡上。