⚛️ React
一句话定性
React 用一句话重写了前端的”牛顿第一定律”:
UI = f(state)。你不再操作 DOM,只声明”给定这个状态,UI 应该长什么样”,剩下的交给虚拟 DOM。这个范式如此根本,以至于十年后所有主流框架——包括它的对手——都建立在它之上。
一、它是什么 & 出现的时代
2013 年 5 月,Facebook 开源 React。它生于 2013-2018 SPA时代 的开端,带着三个在当时离经叛道的概念:虚拟 DOM、JSX、组件即函数。
React 严格来说只是一个视图层(view library),不是全家桶。它的全部哲学浓缩成一个公式:
UI = f(state)—— 界面是状态的纯函数。状态变了,就重新调用这个函数得到新 UI。
// 你只描述"UI 长什么样",从不写"如何改 DOM"
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}二、为什么会出现(解决上一代什么痛点)
AngularJS 的双向绑定带来了新地狱
Facebook 的真实痛点:像”未读消息数”这种状态,在大型应用里散布于多处,手动同步 DOM 几乎不可能不出 bug。而 AngularJS 的双向绑定虽然自动,却带来两个新问题:
- 数据流向不可追踪:数据能从任何方向流动,出 bug 不知道是谁改了谁。
- 脏检查性能崩溃:watcher 一多,运行时全量比对拖垮大型应用。
React 的回答极其大胆:别管怎么改 DOM,你只要每次都”重新描述”整个 UI 长什么样,我在内存里维护一个虚拟 DOM,做 diff,只把变化的部分应用到真实 DOM。它把”如何更新 DOM”的责任,从开发者手里彻底拿走了。 详见 2013-2018 SPA时代。
三、核心创新 & 为什么流行(踩中什么时代红利)
- 虚拟 DOM(Virtual DOM):在内存里用 JS 对象描述 UI,新旧两棵树 diff,最小化真实 DOM 操作。它让”每次重渲染整个 UI”在性能上变得可行——解决了 AngularJS 脏检查的死结。
- 单向数据流:数据自上而下流动(props down),事件自下而上传递(events up)。数据流向单一,出 bug 能顺着追踪——这是对 AngularJS 双向绑定最直接的回应。
- JSX:把 HTML 写进 JS 表达式。
JSX:从群嘲到真香
当时主流信条是”模板和逻辑要分离”。React 反其道而行,把 UI 写进 JS(JSX),初期被骂”亵渎、把 HTML 塞进 JS 里”。但 React 的洞察是:UI 本质上就是逻辑的一部分,放在一起反而更内聚。这个”离经叛道”的选择后来被证明是对的,连 Vue 的渲染函数都支持 JSX。
它踩中了多重时代红利:ES6-ES2015 让 JS 现代化、V8 性能足够、移动互联网爆发要求复杂应用、Facebook 的体量背书。
四、带来的新问题 / 副作用
声明式的胜利,埋下整个时代的痛点
- 首屏白屏 + SEO 灾难:把渲染全搬到客户端,首次加载要先下大坨 JS、再执行、再渲染。用户先看白屏,爬虫看到空
<div id="root">。直接催生 SSG 的回归(Next.js)。- JS bundle 爆炸:框架 + 依赖越来越大,弱网体验崩坏。
- 工具链复杂度失控:用 React 先得会 Webpack、Babel、loader、plugin。“配项目”成了专业技能,催生 2018-2023 工程化时代。
- 状态管理过度工程化:跨组件共享状态难,Redux 出现(单一数据源 + 纯函数 reducer),但样板代码被诟病”改一个值写三个文件”,催生 MobX/Zustand。
- 虚拟 DOM 不是银弹:它有运行时开销,diff 也要成本——这个反思直接催生 Svelte。
五、为什么会衰落 / 现状(仍在用则讲演化)
React 没有衰落,它是事实标准,并且一直在自我革命:
React 的自我进化史
- Hooks(2019)——一场革命:
useState/useEffect让函数组件拥有状态和生命周期,消灭了 class 组件和this的困扰,还让逻辑能跨组件复用(custom hooks),彻底改变了 React 的写法。这是 React 史上影响最深远的一次升级。- Fiber(2017,React 16):重写了协调(reconciliation)引擎,把渲染拆成可中断、可恢复的小单元——为”并发”打地基。
- 并发特性(Concurrent,React 18):可中断渲染、
useTransition、自动批处理,让框架能区分紧急/非紧急更新,提升响应性。- RSC(React Server Components):组件可以在服务端渲染、零客户端 JS,数据获取直接在组件里
await。把战场从客户端推回服务端,试图根治首屏/bundle 问题(详见 渲染模式演进史)。
React 的挑战在于:Hooks 带来了 useEffect 心智负担和闭包陷阱;RSC 又增加了”服务端/客户端”的认知分裂——但它仍牢牢占据生态中心。
六、对后续技术的影响(因果链)
AngularJS 双向绑定不可追踪 + 脏检查性能崩
│
↓
React(2013):UI=f(state) + 虚拟DOM + 单向流 ──► 重新定义前端,成为事实标准
│
├─► JSX ──► "UI即逻辑"理念,被广泛接受
│
├─► 单向数据流 ──► Redux/Flux 状态管理范式
│
├─► 客户端渲染副作用(白屏/SEO/bundle)
│ └─► SSR/SSG 回归 ──► Next.js ──► RSC(回到服务端)
│
├─► 虚拟 DOM 有开销 ──► Svelte(编译时干掉它)、Solid(细粒度响应)
│
└─► 自我进化:Hooks(2019) ─► Fiber ─► 并发(18) ─► RSC
│
↓
影响所有后来者:Vue 借鉴组件化、Composition API 呼应 Hooks
历史地位
React 是 SPA 时代的”工业革命”核心。
UI = f(state)是现代前端的牛顿第一定律,至今所有主流框架都建立其上。它不仅赢得了与 AngularJS 的战争(见 为什么React战胜了AngularJS),更定义了此后十年前端思考问题的方式——从”怎么改 DOM”彻底转向”UI 应该长什么样”。
🔗 相关:前端框架演进史 | AngularJS | Vue | Angular-2+ | Svelte | Redux 🔗 时代:2013-2018 SPA时代 | 2018-2023 工程化时代 🔗 语言:ES6-ES2015 | 渲染:渲染模式演进史 🔗 深度:为什么React战胜了AngularJS